Super PerformanceThe "Super Performance" script is a custom indicator written in Pine Script (version 6) for use on the TradingView platform. Its main purpose is to visually compare the performance of a selected stock or index against a benchmark index (default: NIFTYMIDSML400) over various timeframes, and to display sector-wise performance rankings in a clear, tabular format.
Key Features:
Customizable Display:
Users can toggle between dark and light color themes, enable or disable extended data columns, and choose between a compact "Mini Mode" or a full-featured table view. Table positions and sizes are also configurable for both stock and sector tables.
Performance Calculation:
The script calculates percentage price changes for the selected stock and the benchmark index over multiple periods: 1, 5, 10, 20, 50, and 200 days. It then checks if the stock is outperforming the index for each period.
Conviction Score:
For each period where the stock outperforms the index, a "conviction score" is incremented. This score is mapped to qualitative labels such as "Super solid," "Solid," "Good," etc., and is color-coded for quick visual interpretation.
Sector Performance Table:
The script tracks 19 sector indices (e.g., REALTY, IT, PHARMA, AUTO, ENERGY) and calculates their performance over 1, 5, 10, 20, and 60-day periods. It then ranks the top 5 performing sectors for each timeframe and displays them in a sector performance table.
Visual Output:
Two tables are constructed:
Stock Performance Table: Shows the stock's returns, index returns, outperformance markers (✔/✖), and the difference for each period, along with the overall conviction score.
Sector Performance Table: Ranks and displays the top 5 sectors for each timeframe, with color-coded performance values for easy comparison.
在脚本中搜索" TABLE"
Seasonality DOW CombinedOverall Purpose
This script analyzes historical daily returns based on two specific criteria:
Month of the year (January through December)
Day of the week (Sunday through Saturday)
It summarizes and visually displays the average historical performance of the selected asset by these criteria over multiple years.
Step-by-Step Breakdown
1. Initial Settings:
Defines minimum year (i_year_start) from which data analysis will start.
Ensures the user is using a daily timeframe, otherwise prompts an error.
Sets basic display preferences like text size and color schemes.
2. Data Collection and Variables:
Initializes matrices to store and aggregate returns data:
month_data_ and month_agg_: store monthly performance.
dow_data_ and dow_agg_: store day-of-week performance.
COUNT tracks total number of occurrences, and COUNT_POSITIVE tracks positive-return occurrences.
3. Return Calculation:
Calculates daily percentage change (chg_pct_) in price:
chg_pct_ = close / close - 1
Ensures it captures this data only for the specified years (year >= i_year_start).
4. Monthly Performance Calculation:
Each daily return is grouped by month:
matrix.set updates total returns per month.
The script tracks:
Monthly cumulative returns
Number of occurrences (how many days recorded per month)
Positive occurrences (days with positive returns)
5. Day-of-Week Performance Calculation:
Similarly, daily returns are also grouped by day-of-the-week (Sunday to Saturday):
Daily return values are summed per weekday.
The script tracks:
Cumulative returns per weekday
Number of occurrences per weekday
Positive occurrences per weekday
6. Visual Display (Tables):
The script creates two visual tables:
Left Table: Monthly Performance.
Right Table: Day-of-the-Week Performance.
For each table, it shows:
Yearly data for each month/day.
Summaries at the bottom:
SUM row: Shows total accumulated returns over all selected years for each month/day.
+ive row: Shows percentage (%) of times the month/day had positive returns, along with a tooltip displaying positive occurrences vs total occurrences.
Cells are color-coded:
Green for positive returns.
Red for negative returns.
Gray for neutral/no change.
7. Interpreting the Tables:
Monthly Table (left side):
Helps identify seasonal patterns (e.g., historically bullish/bearish months).
Day-of-Week Table (right side):
Helps detect recurring weekday patterns (e.g., historically bullish Mondays or bearish Fridays).
Practical Use:
Traders use this to:
Identify patterns based on historical data.
Inform trading strategies, e.g., avoiding historically bearish days/months or leveraging historically bullish periods.
Example Interpretation:
If the table shows consistently green (positive) for March and April, historically the asset tends to perform well during spring. Similarly, if the "Friday" column is often red, historically Fridays are bearish for this asset.
The Echo System🔊 The Echo System – Trend + Momentum Trading Strategy
Overview:
The Echo System is a trend-following and momentum-based trading tool designed to identify high-probability buy and sell signals through a combination of market trend analysis, price movement strength, and candlestick validation.
Key Features:
📈 Trend Detection:
Uses a 30 EMA vs. 200 EMA crossover to confirm bullish or bearish trends.
Visual trend strength meter powered by percentile ranking of EMA distance.
🔄 Momentum Check:
Detects significant price moves over the past 6 bars, enhanced by ATR-based scaling to filter weak signals.
🕯️ Candle Confirmation:
Validates recent price action using the previous and current candle body direction.
✅ Smart Conditions Table:
A live dashboard showing all trade condition checks (Trend, Recent Price Move, Candlestick confirmations) in real-time with visual feedback.
📊 Backtesting & Stats:
Auto-calculates average win, average loss, risk-reward ratio (RRR), and win rate across historical signals.
Clean performance dashboard with color-coded metrics for easy reading.
🔔 Alerts:
Set alerts for trade signals or significant price movements to stay updated without monitoring the chart 24/7.
Visuals:
Trend markers and price movement flags plotted directly on the chart.
Dual tables:
📈 Conditions table (top-right): breaks down trade criteria status.
📊 Performance table (bottom-right): shows real-time stats on win/loss and RRR.🔊 The Echo System – Trend + Momentum Trading Strategy
Overview:
The Echo System is a trend-following and momentum-based trading tool designed to identify high-probability buy and sell signals through a combination of market trend analysis, price movement strength, and candlestick validation.
Key Features:
📈 Trend Detection:
Uses a 30 EMA vs. 200 EMA crossover to confirm bullish or bearish trends.
Visual trend strength meter powered by percentile ranking of EMA distance.
🔄 Momentum Check:
Detects significant price moves over the past 6 bars, enhanced by ATR-based scaling to filter weak signals.
🕯️ Candle Confirmation:
Validates recent price action using the previous and current candle body direction.
✅ Smart Conditions Table:
A live dashboard showing all trade condition checks (Trend, Recent Price Move, Candlestick confirmations) in real-time with visual feedback.
📊 Backtesting & Stats:
Auto-calculates average win, average loss, risk-reward ratio (RRR), and win rate across historical signals.
Clean performance dashboard with color-coded metrics for easy reading.
🔔 Alerts:
Set alerts for trade signals or significant price movements to stay updated without monitoring the chart 24/7.
Visuals:
Trend markers and price movement flags plotted directly on the chart.
Dual tables:
📈 Conditions table (top-right): breaks down trade criteria status.
📊 Performance table (bottom-right): shows real-time stats on win/loss and RRR.
ATR Bands with ATR Cross + InfoTableOverview
This Pine Script™ indicator is designed to enhance traders' ability to analyze market volatility, trend direction, and position sizing directly on their TradingView charts. By plotting Average True Range (ATR) bands anchored at the OHLC4 price, displaying crossover labels, and providing a comprehensive information table, this tool offers a multifaceted approach to technical analysis.
Key Features:
ATR Bands Anchored at OHLC4: Visual representation of short-term and long-term volatility bands centered around the average price.
OHLC4 Dotted Line: A dotted line representing the average of Open, High, Low, and Close prices.
ATR Cross Labels: Visual cues indicating when short-term volatility exceeds long-term volatility and vice versa.
Information Table: Displays real-time data on market volatility, calculated position size based on risk parameters, and trend direction relative to the 20-period Smoothed Moving Average (SMMA).
Purpose
The primary purpose of this indicator is to:
Assess Market Volatility: By comparing short-term and long-term ATR values, traders can gauge the current volatility environment.
Determine Optimal Position Sizing: A calculated position size based on user-defined risk parameters helps in effective risk management.
Identify Trend Direction: Comparing the current price to the 20-period SMMA assists in determining the prevailing market trend.
Enhance Decision-Making: Visual cues and real-time data enable traders to make informed trading decisions with greater confidence.
How It Works
1. ATR Bands Anchored at OHLC4
Average True Range (ATR) Calculations
Short-Term ATR (SA): Calculated over a 9-period using ta.atr(9).
Long-Term ATR (LA): Calculated over a 21-period using ta.atr(21).
Plotting the Bands
OHLC4 Dotted Line: Plotted using small circles to simulate a dotted line due to Pine Script limitations.
ATR(9) Bands: Plotted in blue with semi-transparent shading.
ATR(21) Bands: Plotted in orange with semi-transparent shading.
Overlap: Bands can overlap, providing visual insights into changes in volatility.
2. ATR Cross Labels
Crossover Detection:
SA > LA: Indicates increasing short-term volatility.
Detected using ta.crossover(SA, LA).
A green upward label "SA>LA" is plotted below the bar.
SA < LA: Indicates decreasing short-term volatility.
Detected using ta.crossunder(SA, LA).
A red downward label "SA LA, then the market is considered volatile.
Display: Shows "Yes" or "No" based on the comparison.
b. Position Size Calculation
Risk Total Amount: User-defined input representing the total capital at risk.
Risk per 1 Stock: User-defined input representing the risk associated with one unit of the asset.
Purpose: Helps traders determine the appropriate position size based on their risk tolerance and current market volatility.
c. Is Price > 20 SMMA?
SMMA Calculation:
Calculated using a 20-period Smoothed Moving Average with ta.rma(close, 20).
Logic: If the current close price is above the SMMA, the trend is considered upward.
Display: Shows "Yes" or "No" based on the comparison.
How to Use
Step 1: Add the Indicator to Your Chart
Copy the Script: Copy the entire Pine Script code into the TradingView Pine Editor.
Save and Apply: Save the script and click "Add to Chart."
Step 2: Configure Inputs
Risk Parameters: Adjust the "Risk Total Amount" and "Risk per 1 Stock" in the indicator settings to match your personal risk management strategy.
Step 3: Interpret the Visuals
ATR Bands
Width of Bands: Wider bands indicate higher volatility; narrower bands indicate lower volatility.
Band Overlap: Pay attention to areas where the blue and orange bands diverge or converge.
OHLC4 Dotted Line
Serves as a central reference point for the ATR bands.
Helps visualize the average price around which volatility is measured.
ATR Cross Labels
"SA>LA" Label:
Indicates short-term volatility is increasing relative to long-term volatility.
May signal potential breakout or trend acceleration.
"SA 20 SMMA?
Use this to confirm trend direction before entering or exiting trades.
Practical Example
Imagine you are analyzing a stock and notice the following:
ATR(9) Crosses Above ATR(21):
A green "SA>LA" label appears.
The info table shows "Yes" for "Is ATR-based price volatile."
Position Size:
Based on your risk parameters, the position size is calculated.
Price Above 20 SMMA:
The info table shows "Yes" for "Is price > 20 SMMA."
Interpretation:
The market is experiencing increasing short-term volatility.
The trend is upward, as the price is above the 20 SMMA.
You may consider entering a long position, using the calculated position size to manage risk.
Customization
Colors and Transparency:
Adjust the colors of the bands and labels to suit your preferences.
Risk Parameters:
Modify the default values for risk amounts in the inputs.
Moving Average Period:
Change the SMMA period if desired.
Limitations and Considerations
Lagging Indicators: ATR and SMMA are lagging indicators and may not predict future price movements.
Market Conditions: The effectiveness of this indicator may vary across different assets and market conditions.
Risk of Overfitting: Relying solely on this indicator without considering other factors may lead to suboptimal trading decisions.
Conclusion
This indicator combines essential elements of technical analysis to provide a comprehensive tool for traders. By visualizing ATR bands anchored at the OHLC4, indicating volatility crossovers, and providing real-time data on position sizing and trend direction, it aids in making informed trading decisions.
Whether you're a novice trader looking to understand market volatility or an experienced trader seeking to refine your strategy, this indicator offers valuable insights directly on your TradingView charts.
Code Summary
The script is written in Pine Script™ version 5 and includes:
Calculations for OHLC4, ATRs, Bands, SMMA:
Uses built-in functions like ta.atr() and ta.rma() for calculations.
Plotting Functions:
plotshape() for the OHLC4 dotted line.
plot() and fill() for the ATR bands.
Crossover Detection:
ta.crossover() and ta.crossunder() for detecting ATR crosses.
Labeling Crossovers:
label.new() to place informative labels on the chart.
Information Table Creation:
table.new() to create the table.
table.cell() to populate it with data.
Acknowledgments
ATR and SMMA Concepts: Built upon standard technical analysis concepts widely used in trading.
Pine Script™: Leveraged the capabilities of Pine Script™ version 5 for advanced charting and analysis.
Note: Always test any indicator thoroughly and consider combining it with other forms of analysis before making trading decisions. Trading involves risk, and past performance is not indicative of future results.
Happy Trading!
RSI Overbought/Oversold + Divergence Indicator (new)//@version=5
indicator('CryptoSignalScanner - RSI Overbought/Oversold + Divergence Indicator (new)',
//---------------------------------------------------------------------------------------------------------------------------------
//--- Define Colors ---------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------
vWhite = #FFFFFF
vViolet = #C77DF3
vIndigo = #8A2BE2
vBlue = #009CDF
vGreen = #5EBD3E
vYellow = #FFB900
vRed = #E23838
longColor = color.green
shortColor = color.red
textColor = color.white
bullishColor = color.rgb(38,166,154,0) //Used in the display table
bearishColor = color.rgb(239,83,79,0) //Used in the display table
nomatchColor = color.silver //Used in the display table
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Functions--------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
TF2txt(TF) =>
switch TF
"S" => "RSI 1s:"
"5S" => "RSI 5s:"
"10S" => "RSI 10s:"
"15S" => "RSI 15s:"
"30S" => "RSI 30s"
"1" => "RSI 1m:"
"3" => "RSI 3m:"
"5" => "RSI 5m:"
"15" => "RSI 15m:"
"30" => "RSI 30m"
"45" => "RSI 45m"
"60" => "RSI 1h:"
"120" => "RSI 2h:"
"180" => "RSI 3h:"
"240" => "RSI 4h:"
"480" => "RSI 8h:"
"D" => "RSI 1D:"
"1D" => "RSI 1D:"
"2D" => "RSI 2D:"
"3D" => "RSI 2D:"
"3D" => "RSI 3W:"
"W" => "RSI 1W:"
"1W" => "RSI 1W:"
"M" => "RSI 1M:"
"1M" => "RSI 1M:"
"3M" => "RSI 3M:"
"6M" => "RSI 6M:"
"12M" => "RSI 12M:"
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Show/Hide Settings ----------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
rsiShowInput = input(true, title='Show RSI', group='Show/Hide Settings')
maShowInput = input(false, title='Show MA', group='Show/Hide Settings')
showRSIMAInput = input(true, title='Show RSIMA Cloud', group='Show/Hide Settings')
rsiBandShowInput = input(true, title='Show Oversold/Overbought Lines', group='Show/Hide Settings')
rsiBandExtShowInput = input(true, title='Show Oversold/Overbought Extended Lines', group='Show/Hide Settings')
rsiHighlightShowInput = input(true, title='Show Oversold/Overbought Highlight Lines', group='Show/Hide Settings')
DivergenceShowInput = input(true, title='Show RSI Divergence Labels', group='Show/Hide Settings')
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Table Settings --------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
rsiShowTable = input(true, title='Show RSI Table Information box', group="RSI Table Settings")
rsiTablePosition = input.string(title='Location', defval='middle_right', options= , group="RSI Table Settings", inline='1')
rsiTextSize = input.string(title=' Size', defval='small', options= , group="RSI Table Settings", inline='1')
rsiShowTF1 = input(true, title='Show TimeFrame1', group="RSI Table Settings", inline='tf1')
rsiTF1 = input.timeframe("15", title=" Time", group="RSI Table Settings", inline='tf1')
rsiShowTF2 = input(true, title='Show TimeFrame2', group="RSI Table Settings", inline='tf2')
rsiTF2 = input.timeframe("60", title=" Time", group="RSI Table Settings", inline='tf2')
rsiShowTF3 = input(true, title='Show TimeFrame3', group="RSI Table Settings", inline='tf3')
rsiTF3 = input.timeframe("240", title=" Time", group="RSI Table Settings", inline='tf3')
rsiShowTF4 = input(true, title='Show TimeFrame4', group="RSI Table Settings", inline='tf4')
rsiTF4 = input.timeframe("D", title=" Time", group="RSI Table Settings", inline='tf4')
rsiShowHist = input(true, title='Show RSI Historical Columns', group="RSI Table Settings", tooltip='Show the information of the 2 previous closed candles')
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- RSI Input Settings ----------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
rsiSourceInput = input.source(close, 'Source', group='RSI Settings')
rsiLengthInput = input.int(14, minval=1, title='RSI Length', group='RSI Settings', tooltip='Here we set the RSI lenght')
rsiColorInput = input.color(#26a69a, title="RSI Color", group='RSI Settings')
rsimaColorInput = input.color(#ef534f, title="RSIMA Color", group='RSI Settings')
rsiBandColorInput = input.color(#787B86, title="RSI Band Color", group='RSI Settings')
rsiUpperBandExtInput = input.int(title='RSI Overbought Extended Line', defval=80, minval=50, maxval=100, group='RSI Settings')
rsiUpperBandInput = input.int(title='RSI Overbought Line', defval=70, minval=50, maxval=100, group='RSI Settings')
rsiLowerBandInput = input.int(title='RSI Oversold Line', defval=30, minval=0, maxval=50, group='RSI Settings')
rsiLowerBandExtInput = input.int(title='RSI Oversold Extended Line', defval=20, minval=0, maxval=50, group='RSI Settings')
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- MA Input Settings -----------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
maTypeInput = input.string("EMA", title="MA Type", options= , group="MA Settings")
maLengthInput = input.int(14, title="MA Length", group="MA Settings")
maColorInput = input.color(color.yellow, title="MA Color", group='MA Settings') //#7E57C2
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Divergence Input Settings ---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
lbrInput = input(title="Pivot Lookback Right", defval=2, group='RSI Divergence Settings')
lblInput = input(title="Pivot Lookback Left", defval=2, group='RSI Divergence Settings')
lbRangeMaxInput = input(title="Max of Lookback Range", defval=10, group='RSI Divergence Settings')
lbRangeMinInput = input(title="Min of Lookback Range", defval=2, group='RSI Divergence Settings')
plotBullInput = input(title="Plot Bullish", defval=true, group='RSI Divergence Settings')
plotHiddenBullInput = input(title="Plot Hidden Bullish", defval=true, group='RSI Divergence Settings')
plotBearInput = input(title="Plot Bearish", defval=true, group='RSI Divergence Settings')
plotHiddenBearInput = input(title="Plot Hidden Bearish", defval=true, group='RSI Divergence Settings')
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- RSI Calculation -------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
rsi = ta.rsi(rsiSourceInput, rsiLengthInput)
rsiprevious = rsi
= request.security(syminfo.tickerid, rsiTF1, [rsi, rsi , rsi ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, rsiTF2, [rsi, rsi , rsi ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, rsiTF3, [rsi, rsi , rsi ], lookahead=barmerge.lookahead_on)
= request.security(syminfo.tickerid, rsiTF4, [rsi, rsi , rsi ], lookahead=barmerge.lookahead_on)
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- MA Calculation -------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
ma(source, length, type) =>
switch type
"SMA" => ta.sma(source, length)
"Bollinger Bands" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"SMMA (RMA)" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"VWMA" => ta.vwma(source, length)
rsiMA = ma(rsi, maLengthInput, maTypeInput)
rsiMAPrevious = rsiMA
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Stoch RSI Settings + Calculation --------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
showStochRSI = input(false, title="Show Stochastic RSI", group='Stochastic RSI Settings')
smoothK = input.int(title="Stochastic K", defval=3, minval=1, maxval=10, group='Stochastic RSI Settings')
smoothD = input.int(title="Stochastic D", defval=4, minval=1, maxval=10, group='Stochastic RSI Settings')
lengthRSI = input.int(title="Stochastic RSI Lenght", defval=14, minval=1, group='Stochastic RSI Settings')
lengthStoch = input.int(title="Stochastic Lenght", defval=14, minval=1, group='Stochastic RSI Settings')
colorK = input.color(color.rgb(41,98,255,0), title="K Color", group='Stochastic RSI Settings', inline="1")
colorD = input.color(color.rgb(205,109,0,0), title="D Color", group='Stochastic RSI Settings', inline="1")
StochRSI = ta.rsi(rsiSourceInput, lengthRSI)
k = ta.sma(ta.stoch(StochRSI, StochRSI, StochRSI, lengthStoch), smoothK) //Blue Line
d = ta.sma(k, smoothD) //Red Line
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Divergence Settings ------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
bearColor = color.red
bullColor = color.green
hiddenBullColor = color.new(color.green, 50)
hiddenBearColor = color.new(color.red, 50)
//textColor = color.white
noneColor = color.new(color.white, 100)
osc = rsi
plFound = na(ta.pivotlow(osc, lblInput, lbrInput)) ? false : true
phFound = na(ta.pivothigh(osc, lblInput, lbrInput)) ? false : true
_inRange(cond) =>
bars = ta.barssince(cond == true)
lbRangeMinInput <= bars and bars <= lbRangeMaxInput
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Define Plot & Line Colors ---------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
rsiColor = rsi >= rsiMA ? rsiColorInput : rsimaColorInput
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Plot Lines ------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Create a horizontal line at a specific price level
myLine = line.new(bar_index , 75, bar_index, 75, color = color.rgb(187, 14, 14), width = 2)
bottom = line.new(bar_index , 50, bar_index, 50, color = color.rgb(223, 226, 28), width = 2)
mymainLine = line.new(bar_index , 60, bar_index, 60, color = color.rgb(13, 154, 10), width = 3)
hline(50, title='RSI Baseline', color=color.new(rsiBandColorInput, 50), linestyle=hline.style_solid, editable=false)
hline(rsiBandExtShowInput ? rsiUpperBandExtInput : na, title='RSI Upper Band', color=color.new(rsiBandColorInput, 10), linestyle=hline.style_dashed, editable=false)
hline(rsiBandShowInput ? rsiUpperBandInput : na, title='RSI Upper Band', color=color.new(rsiBandColorInput, 10), linestyle=hline.style_dashed, editable=false)
hline(rsiBandShowInput ? rsiLowerBandInput : na, title='RSI Upper Band', color=color.new(rsiBandColorInput, 10), linestyle=hline.style_dashed, editable=false)
hline(rsiBandExtShowInput ? rsiLowerBandExtInput : na, title='RSI Upper Band', color=color.new(rsiBandColorInput, 10), linestyle=hline.style_dashed, editable=false)
bgcolor(rsiHighlightShowInput ? rsi >= rsiUpperBandExtInput ? color.new(rsiColorInput, 70) : na : na, title="Show Extended Oversold Highlight", editable=false)
bgcolor(rsiHighlightShowInput ? rsi >= rsiUpperBandInput ? rsi < rsiUpperBandExtInput ? color.new(#64ffda, 90) : na : na: na, title="Show Overbought Highlight", editable=false)
bgcolor(rsiHighlightShowInput ? rsi <= rsiLowerBandInput ? rsi > rsiLowerBandExtInput ? color.new(#F43E32, 90) : na : na : na, title="Show Extended Oversold Highlight", editable=false)
bgcolor(rsiHighlightShowInput ? rsi <= rsiLowerBandInput ? color.new(rsimaColorInput, 70) : na : na, title="Show Oversold Highlight", editable=false)
maPlot = plot(maShowInput ? rsiMA : na, title='MA', color=color.new(maColorInput,0), linewidth=1)
rsiMAPlot = plot(showRSIMAInput ? rsiMA : na, title="RSI EMA", color=color.new(rsimaColorInput,0), editable=false, display=display.none)
rsiPlot = plot(rsiShowInput ? rsi : na, title='RSI', color=color.new(rsiColor,0), linewidth=1)
fill(rsiPlot, rsiMAPlot, color=color.new(rsiColor, 60), title="RSIMA Cloud")
plot(showStochRSI ? k : na, title='Stochastic K', color=colorK, linewidth=1)
plot(showStochRSI ? d : na, title='Stochastic D', color=colorD, linewidth=1)
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Plot Divergence -------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Regular Bullish
// Osc: Higher Low
oscHL = osc > ta.valuewhen(plFound, osc , 1) and _inRange(plFound )
// Price: Lower Low
priceLL = low < ta.valuewhen(plFound, low , 1)
bullCond = plotBullInput and priceLL and oscHL and plFound
plot(
plFound ? osc : na,
offset=-lbrInput,
title="Regular Bullish",
linewidth=2,
color=(bullCond ? bullColor : noneColor)
)
plotshape(
DivergenceShowInput ? bullCond ? osc : na : na,
offset=-lbrInput,
title="Regular Bullish Label",
text=" Bull ",
style=shape.labelup,
location=location.absolute,
color=bullColor,
textcolor=textColor
)
//------------------------------------------------------------------------------
// Hidden Bullish
// Osc: Lower Low
oscLL = osc < ta.valuewhen(plFound, osc , 1) and _inRange(plFound )
// Price: Higher Low
priceHL = low > ta.valuewhen(plFound, low , 1)
hiddenBullCond = plotHiddenBullInput and priceHL and oscLL and plFound
plot(
plFound ? osc : na,
offset=-lbrInput,
title="Hidden Bullish",
linewidth=2,
color=(hiddenBullCond ? hiddenBullColor : noneColor)
)
plotshape(
DivergenceShowInput ? hiddenBullCond ? osc : na : na,
offset=-lbrInput,
title="Hidden Bullish Label",
text=" H Bull ",
style=shape.labelup,
location=location.absolute,
color=bullColor,
textcolor=textColor
)
//------------------------------------------------------------------------------
// Regular Bearish
// Osc: Lower High
oscLH = osc < ta.valuewhen(phFound, osc , 1) and _inRange(phFound )
// Price: Higher High
priceHH = high > ta.valuewhen(phFound, high , 1)
bearCond = plotBearInput and priceHH and oscLH and phFound
plot(
phFound ? osc : na,
offset=-lbrInput,
title="Regular Bearish",
linewidth=2,
color=(bearCond ? bearColor : noneColor)
)
plotshape(
DivergenceShowInput ? bearCond ? osc : na : na,
offset=-lbrInput,
title="Regular Bearish Label",
text=" Bear ",
style=shape.labeldown,
location=location.absolute,
color=bearColor,
textcolor=textColor
)
//------------------------------------------------------------------------------
// Hidden Bearish
// Osc: Higher High
oscHH = osc > ta.valuewhen(phFound, osc , 1) and _inRange(phFound )
// Price: Lower High
priceLH = high < ta.valuewhen(phFound, high , 1)
hiddenBearCond = plotHiddenBearInput and priceLH and oscHH and phFound
plot(
phFound ? osc : na,
offset=-lbrInput,
title="Hidden Bearish",
linewidth=2,
color=(hiddenBearCond ? hiddenBearColor : noneColor)
)
plotshape(
DivergenceShowInput ? hiddenBearCond ? osc : na : na,
offset=-lbrInput,
title="Hidden Bearish Label",
text=" H Bear ",
style=shape.labeldown,
location=location.absolute,
color=bearColor,
textcolor=textColor
)
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Check RSI Lineup ------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
bullTF = rsi > rsi and rsi > rsi
bearTF = rsi < rsi and rsi < rsi
bullTF1 = rsi1 > rsi1_1 and rsi1_1 > rsi1_2
bearTF1 = rsi1 < rsi1_1 and rsi1_1 < rsi1_2
bullTF2 = rsi2 > rsi2_1 and rsi2_1 > rsi2_2
bearTF2 = rsi2 < rsi2_1 and rsi2_1 < rsi2_2
bullTF3 = rsi3 > rsi3_1 and rsi3_1 > rsi3_2
bearTF3 = rsi3 < rsi3_1 and rsi3_1 < rsi3_2
bullTF4 = rsi4 > rsi4_1 and rsi4_1 > rsi4_2
bearTF4 = rsi4 < rsi4_1 and rsi4_1 < rsi4_2
bbTxt(bull,bear) =>
bull ? "BULLISH" : bear ? "BEARISCH" : 'NO LINEUP'
bbColor(bull,bear) =>
bull ? bullishColor : bear ? bearishColor : nomatchColor
newTC(tBox, col, row, txt, width, txtColor, bgColor, txtHA, txtSize) =>
table.cell(table_id=tBox,column=col, row=row, text=txt, width=width,text_color=txtColor,bgcolor=bgColor, text_halign=txtHA, text_size=txtSize)
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--- Define RSI Table Setting ----------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
width_c0 = 0
width_c1 = 0
if rsiShowTable
var tBox = table.new(position=rsiTablePosition, columns=5, rows=6, bgcolor=color.rgb(18,22,33,50), frame_color=color.black, frame_width=1, border_color=color.black, border_width=1)
newTC(tBox, 0,1,"RSI Current",width_c0,color.orange,color.rgb(0,0,0,100),'right',rsiTextSize)
newTC(tBox, 1,1,str.format(" {0,number,#.##} ", rsi),width_c0,vWhite,rsi < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 4,1,bbTxt(bullTF, bearTF),width_c0,vWhite,bbColor(bullTF, bearTF),'center',rsiTextSize)
if rsiShowHist
newTC(tBox, 2,1,str.format(" {0,number,#.##} ", rsi ),width_c0,vWhite,rsi < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 3,1,str.format(" {0,number,#.##} ", rsi ),width_c0,vWhite,rsi < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
if rsiShowTF1
newTC(tBox, 0,2,TF2txt(rsiTF1),width_c0,vWhite,color.rgb(0,0,0,100),'right',rsiTextSize)
newTC(tBox, 1,2,str.format(" {0,number,#.##} ", rsi1),width_c0,vWhite,rsi1 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 4,2,bbTxt(bullTF1, bearTF1),width_c0,vWhite,bbColor(bullTF1,bearTF1),'center',rsiTextSize)
if rsiShowHist
newTC(tBox, 2,2,str.format(" {0,number,#.##} ", rsi1_1),width_c0,vWhite,rsi1_1 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 3,2,str.format(" {0,number,#.##} ", rsi1_2),width_c0,vWhite,rsi1_2 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
if rsiShowTF2
newTC(tBox, 0,3,TF2txt(rsiTF2),width_c0,vWhite,color.rgb(0,0,0,100),'right',rsiTextSize)
newTC(tBox, 1,3,str.format(" {0,number,#.##} ", rsi2),width_c0,vWhite,rsi2 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 4,3,bbTxt(bullTF2, bearTF2),width_c0,vWhite,bbColor(bullTF2,bearTF2),'center',rsiTextSize)
if rsiShowHist
newTC(tBox, 2,3,str.format(" {0,number,#.##} ", rsi2_1),width_c0,vWhite,rsi2_1 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 3,3,str.format(" {0,number,#.##} ", rsi2_2),width_c0,vWhite,rsi2_2 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
if rsiShowTF3
newTC(tBox, 0,4,TF2txt(rsiTF3),width_c0,vWhite,color.rgb(0,0,0,100),'right',rsiTextSize)
newTC(tBox, 1,4,str.format(" {0,number,#.##} ", rsi3),width_c0,vWhite,rsi3 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 4,4,bbTxt(bullTF3, bearTF3),width_c0,vWhite,bbColor(bullTF3,bearTF3),'center',rsiTextSize)
if rsiShowHist
newTC(tBox, 2,4,str.format(" {0,number,#.##} ", rsi3_1),width_c0,vWhite,rsi3_1 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 3,4,str.format(" {0,number,#.##} ", rsi3_2),width_c0,vWhite,rsi3_2 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
if rsiShowTF4
newTC(tBox, 0,5,TF2txt(rsiTF4),width_c0,vWhite,color.rgb(0,0,0,100),'right',rsiTextSize)
newTC(tBox, 1,5,str.format(" {0,number,#.##} ", rsi4),width_c0,vWhite,rsi4 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 4,5,bbTxt(bullTF4, bearTF4),width_c0,vWhite,bbColor(bullTF4,bearTF4),'center',rsiTextSize)
if rsiShowHist
newTC(tBox, 2,5,str.format(" {0,number,#.##} ", rsi4_1),width_c0,vWhite,rsi4_1 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
newTC(tBox, 3,5,str.format(" {0,number,#.##} ", rsi4_2),width_c0,vWhite,rsi4_2 < 50 ? bearishColor:bullishColor,'left',rsiTextSize)
//------------------------------------------------------
//--- Alerts -------------------------------------------
//------------------------------------------------------
Triad Trade MatrixOverview
Triad Trade Matrix is an advanced multi-strategy indicator built using Pine Script v5. It is designed to simultaneously track and display key trading metrics for three distinct trading styles on a single chart:
Swing Trading (Swing Supreme):
This mode captures longer-term trends and is designed for trades that typically span several days. It uses customizable depth and deviation parameters to determine swing signals.
Day Trading (Day Blaze):
This mode focuses on intraday price movements. It generates signals that are intended to be executed within a single trading session. The parameters for depth and deviation are tuned to capture more frequent, shorter-term moves.
Scalping (Scalp Surge):
This mode is designed for very short-term trades where quick entries and exits are key. It uses more sensitive parameters to detect rapid price movements suitable for scalping strategies.
Each trading style is represented by its own merged table that displays real-time metrics. The tables update automatically as new trading signals are generated.
Key Features
Multi-Style Tracking:
Swing Supreme (Large): For swing trading; uses a purple theme.
Day Blaze (Medium): For day trading; uses an orange theme.
Scalp Surge (Small): For scalping; uses a green theme.
Real-Time Metrics:
Each table displays key trade metrics including:
Entry Price: The price at which the trade was entered.
Exit Price: The price at which the previous trade was exited.
Position Size: Calculated as the account size divided by the entry price.
Direction: Indicates whether the trade is “Up” (long) or “Down” (short).
Time: The time when the trade was executed (formatted to hours and minutes).
Wins/Losses: The cumulative number of winning and losing trades.
Current Price & PnL: The current price on the chart and the profit/loss computed relative to the entry price.
Duration: The number of bars that the trade has been open.
History Column: A merged summary column that shows the most recent trade’s details (entry, exit, and result).
Customizability:
Column Visibility: Users can toggle individual columns (Ticker, Timeframe, Entry, Exit, etc.) on or off according to their preference.
Appearance Settings: You can customize the table border width, frame color, header background, and text colors.
History Toggle: The merged history column can be enabled or disabled.
Chart Markers: There is an option to show or hide chart markers (labels and lines) that indicate trade entries and exits on the chart.
Trade History Management:
The indicator maintains a rolling history (up to three recent trades per trading style) and displays the latest summary in the merged table.
This history column provides a quick reference to recent performance.
How It Works
Signal Generation & Trade Metrics
Trade Entry/Exit Calculation:
For each trading style, the indicator uses built-in functions (such as ta.lowestbars and ta.highestbars) to analyze price movements. Based on a customizable "depth" and "deviation" parameter, it determines the point of entry for a trade.
Swing Supreme: Uses larger depth/deviation values to capture swing trends.
Day Blaze: Uses intermediate values for intraday moves.
Scalp Surge: Uses tighter parameters to pick up rapid price changes.
Metrics Update:
When a new trade signal is generated (i.e., when the trade entry price is updated), the indicator calculates:
The current PnL as the difference between the current price and the entry price (or vice versa, depending on the trade direction).
The duration as the number of bars since the trade was opened.
The position size using the formula: accountSize / entryPrice.
History Recording:
Each time a new trade is triggered (i.e., when the entry price is updated), a summary string is created (showing entry, exit, and win/loss status) and appended to the corresponding trade history array. The merged table then displays the latest summary from this history.
Table Display
Merged Table Structure:
Each trading style (Swing Supreme, Day Blaze, and Scalp Surge) is represented by a table that has 15 columns. The columns are:
Trade Type (e.g., Swing Supreme)
Ticker
Timeframe
Entry Price
Exit Price
Position Size
Direction
Time of Entry
Account Size
Wins
Losses
Current Price
Current PnL
Duration (in bars)
History (the latest trade summary)
User Customization:
Through the settings panel, users can choose which columns to display.
If a column is toggled off, its cells will remain blank, allowing traders to focus on the metrics that matter most to them.
Appearance & Themes:
The table headers and cell backgrounds are customizable via color inputs. The trading style names are color-coded:
Swing Supreme (Large): Uses a purple theme.
Day Blaze (Medium): Uses an orange theme.
Scalp Surge (Small): Uses a green theme.
How to Use the Indicator
Add the Indicator to Your Chart:
Once published, add "Triad Trade Matrix" to your TradingView chart.
Configure the Settings:
Adjust the Account Size to match your trading capital.
Use the Depth and Deviation inputs for each trading style to fine-tune the signal sensitivity.
Toggle the Chart Markers on if you want visual entry/exit markers on the chart.
Customize which columns are visible via the column visibility toggles.
Enable or disable the History Column to show the merged trade history in the table.
Adjust the appearance settings (colors, border width, etc.) to suit your chart background and preferences.
Interpret the Tables:
Swing Supreme:
This table shows metrics for swing trades.
Look for changes in entry price, PnL, and trade duration to monitor longer-term moves.
Day Blaze:
This table tracks day trading activity.It will update more frequently, reflecting intraday trends.
Scalp Surge:
This table is dedicated to scalping signals.Use it to see quick entry/exit data and rapid profit/loss changes.
The History column (if enabled) gives you a snapshot of the most recent trade (e.g., "E:123.45 X:124.00 Up Win").
Use allerts:
The indicator includes alert condition for new trade entries(both long and short)for each trading style.
Summary:
Triad Trade Matrix provides an robust,multi-dimensional view of your trading performance across swing trading, day trading, and scalping.
Best to be used whith my other indicators
True low high
Vma Ext_Adv_CustomTbl
This indicator is ideal for traders who wish to monitor multiple trading styles simultaneously, with a clear, technical, and real-time display of performance metrics.
Happy Trading!
ICT Killzones & FVG// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © Mutharasan12
//@version=5
indicator("ICT Killzones & FVG", "ICT Killzones & FVG", overlay = true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)
// ---------------------------------------- Constant Functions --------------------------------------------------
get_line_type(_style) =>
result = switch _style
'Solid' => line.style_solid
'Dotted' => line.style_dotted
'Dashed' => line.style_dashed
result
get_size(x) =>
result = switch x
'Auto' => size.auto
'Tiny' => size.tiny
'Small' => size.small
'Normal' => size.normal
'Large' => size.large
'Huge' => size.huge
get_table_pos(pos) =>
result = switch pos
"Bottom Center" => position.bottom_center
"Bottom Left" => position.bottom_left
"Bottom Right" => position.bottom_right
"Middle Center" => position.middle_center
"Middle Left" => position.middle_left
"Middle Right" => position.middle_right
"Top Center" => position.top_center
"Top Left" => position.top_left
"Top Right" => position.top_right
get_font_style(s) =>
result = switch s
'Monospace' => font.family_monospace
'Default' => font.family_default
// ---------------------------------------- Constant Functions --------------------------------------------------
// ---------------------------------------- Inputs --------------------------------------------------
gmt_tz = input.string('America/New_York', "Timezone", options = , tooltip = "Note GMT is not adjusted to reflect Daylight Saving Time changes", group = 'Time Zone')
DWM_profile = input.bool(true,"Show All Profile",inline="Show",group = 'Profile')
D_profile = input.bool(true,"Show Daily",inline = "Show",group = 'Profile')
hide_lines_DO = input.timeframe("60","Daily:",inline = "Hide",group = 'Hide Above')
W_profile = input.bool(true,"Weekly",inline="Show",group = 'Profile')
hide_lines_WO = input.timeframe("240","Weekly:",inline="Hide",group = 'Hide Above')
M_profile = input.bool(true,"Monthly",inline="Show",group = 'Profile')
hide_lines_MO = input.timeframe("1D","Monthly:",inline="Hide",group = 'Hide Above')
show_kz = input.bool(false, "Show Killzone Boxes", inline = "skz", group = 'Hide KillZone')
var g_SETTINGS = "Settings"
max_days = input.int(60, "Drawing Limit", 1, inline = 'dl', tooltip = "Only this many drawings will be kept on the chart, for each selected drawing type (killzone boxes, pivot lines, open lines, etc.)", group = g_SETTINGS)
tf_limit = input.timeframe("30", "Timeframe Limit", inline = 'dl', tooltip = "Drawings will not appear on timeframes greater than or equal to this", group = g_SETTINGS)
lbl_size = get_size(input.string('Tiny', "Label Size", inline = 'sc', options = , tooltip = "The size of all labels", group = g_SETTINGS))
font_style = get_font_style(input.string('Monospace', "Font Style", inline = 'sc', group = g_SETTINGS, options = ))
txt_color = input.color(#000000, "Text Color", inline = 'sc', tooltip = "The color of all label and table text", group = g_SETTINGS)
use_cutoff = input.bool(true, "Drawing Cutoff Time", inline = "CO", tooltip = "When enabled, all pivots and open price lines will stop extending at this time", group = g_SETTINGS)
cutoff = input.session("1700-1701", "", inline = "CO", group = g_SETTINGS)
var g_KZ = "Killzones"
show_kz_text = input.bool(false, "Display Text", inline = "KZ", group = g_KZ)
box_transparency = input.int(85, "Box Transparency", 0, 100, group = g_KZ)
text_transparency = input.int(50, "Text Transparency", 0, 100, group = g_KZ)
use_asia = input.bool(true, "", inline = "ASIA", group = g_KZ)
as_txt = input.string("ASIA", "", inline = "ASIA", group = g_KZ)
asia = input.session("2000-0000", "", inline = "ASIA", group = g_KZ)
as_color = input.color(#9598a1, "", inline = "ASIA", group = g_KZ)
use_london = input.bool(true, "", inline = "LONDON", group = g_KZ)
lo_txt = input.string("OPEN", "", inline = "LONDON", group = g_KZ)
london = input.session("0200-0500", "", inline = "LONDON", group = g_KZ)
lo_color = input.color(#9598a1, "", inline = "LONDON", group = g_KZ)
use_nyam = input.bool(true, "", inline = "NYAM", group = g_KZ)
na_txt = input.string("NYAM", "", inline = "NYAM", group = g_KZ)
nyam = input.session("0700-1000", "", inline = "NYAM", group = g_KZ)
na_color = input.color(#9598a1, "", inline = "NYAM", group = g_KZ)
use_nylu = input.bool(false, "", inline = "NYLU", group = g_KZ)
nl_txt = input.string("Lunch", "", inline = "NYLU", group = g_KZ)
nylu = input.session("1200-1300", "", inline = "NYLU", group = g_KZ)
nl_color = input.color(#9598a1, "", inline = "NYLU", group = g_KZ)
use_nypm = input.bool(false, "", inline = "NYPM", group = g_KZ)
np_txt = input.string("NYPM", "", inline = "NYPM", group = g_KZ)
nypm = input.session("1300-1600", "", inline = "NYPM", group = g_KZ)
np_color = input.color(#9598a1, "", inline = "NYPM", group = g_KZ)
use_loop = input.bool(true, "", inline = "LOOP", group = g_KZ)
op_txt = input.string("CBDR", "", inline = "LOOP", group = g_KZ)
loop = input.session("1400-2000", "", inline = "LOOP", group = g_KZ)
op_color = input.color(#9598a1, "", inline = "LOOP", group = g_KZ)
use_locl = input.bool(true, "", inline = "LOCL", group = g_KZ)
cl_txt = input.string("CLOSE", "", inline = "LOCL", group = g_KZ)
locl = input.session("1000-1200", "", inline = "LOCL", group = g_KZ)
cl_color = input.color(#9598a1, "", inline = "LOCL", group = g_KZ)
use_sb1 = input.bool(false, "", inline = "SB1", group = g_KZ)
m1_txt = input.string("London SB", "", inline = "SB1", group = g_KZ)
sb1 = input.session("0300-0400", "", inline = "SB1", group = g_KZ)
m1_color = input.color(#9598a1, "", inline = "SB1", group = g_KZ)
use_sb2 = input.bool(false, "", inline = "SB2", group = g_KZ)
m2_txt = input.string("NewYork AM SB", "", inline = "SB2", group = g_KZ)
sb2 = input.session("1000-1100", "", inline = "SB2", group = g_KZ)
m2_color = input.color(#9598a1, "", inline = "SB2", group = g_KZ)
use_sb3 = input.bool(false, "", inline = "SB3", group = g_KZ)
m3_txt = input.string("NewYork PM SB", "", inline = "SB3", group = g_KZ)
sb3 = input.session("1400-1500", "", inline = "SB3", group = g_KZ)
m3_color = input.color(#9598a1, "", inline = "SB3", group = g_KZ)
var g_LABELS = "Killzone Pivots"
use_alerts = input.bool(false, "Alert Broken Pivots", inline = "PV", group = g_LABELS)
show_pivots = input.bool(false, "Show Pivots", inline = "SV", group = g_LABELS)
show_labels = input.bool(false, "Pivots Labels", inline = "SV", group = g_LABELS)
show_midpoints = input.bool(false, "Pivots Midpoints",inline = "SV", group = g_LABELS)
ext_pivots = input.string("Until Mitigated", "Extend Pivots...", options = , group = g_LABELS)
ext_which = input.string("Most Recent", "...From Which Sessions", options = , group = g_LABELS)
ash_str = input.string("AS.H", "Killzone 01 Labels", inline = "L_AS", group = g_LABELS)
asl_str = input.string("AS.L", "", inline = "L_AS", group = g_LABELS)
loh_str = input.string("LO.H", "Killzone 02 Labels", inline = "L_LO", group = g_LABELS)
lol_str = input.string("LO.L", "", inline = "L_LO", group = g_LABELS)
nah_str = input.string("NYAM.H", "Killzone 03 Labels", inline = "L_NA", group = g_LABELS)
nal_str = input.string("NYAM.L", "", inline = "L_NA", group = g_LABELS)
nlh_str = input.string("NYL.H", "Killzone 04 Labels", inline = "L_NL", group = g_LABELS)
nll_str = input.string("NYL.L", "", inline = "L_NL", group = g_LABELS)
nph_str = input.string("NYPM.H", "Killzone 05 Labels", inline = "L_NP", group = g_LABELS)
npl_str = input.string("NYPM.L", "", inline = "L_NP", group = g_LABELS)
oph_str = input.string("LOOP.H", "Killzone 06 Labels", inline = "L_OP", group = g_LABELS)
opl_str = input.string("LOOP.L", "", inline = "L_OP", group = g_LABELS)
clh_str = input.string("LOCL.H", "Killzone 07 Labels", inline = "L_CL", group = g_LABELS)
cll_str = input.string("LOCL.L", "", inline = "L_CL", group = g_LABELS)
m1h_str = input.string("SB1.H", "Killzone 08 Labels", inline = "L_M1", group = g_LABELS)
m1l_str = input.string("SB1.L", "", inline = "L_M1", group = g_LABELS)
m2h_str = input.string("SB2.H", "Killzone 09 Labels", inline = "L_M2", group = g_LABELS)
m2l_str = input.string("SB2.L", "", inline = "L_M2", group = g_LABELS)
m3h_str = input.string("SB3.H", "Killzone 10 Labels", inline = "L_M3", group = g_LABELS)
m3l_str = input.string("SB3.L", "", inline = "L_M3", group = g_LABELS)
kzp_style = get_line_type(input.string(defval = 'Solid', title = "Pivot Style", options = , inline = "KZP", group = g_LABELS))
kzp_width = input.int(1, "", inline = "KZP", group = g_LABELS)
kzm_style = get_line_type(input.string(defval = 'Dotted', title = "Midpoint Style", options = , inline = "KZM", group = g_LABELS))
kzm_width = input.int(1, "", inline = "KZM", group = g_LABELS)
var g_RNG = "Killzone Range"
show_range = input.bool(false, "Show Killzone Range", tooltip = "Show the most recent ranges of each selected killzone, from high to low", group = g_RNG)
show_range_avg = input.bool(true, "Show Average", tooltip = "Show the average range of each selected killzone", group = g_RNG)
range_avg = input.int(5, "Average Length", 0, tooltip = "This many previous sessions will be used to calculate the average. If there isn't enough data on the current chart, it will use as many sessions as possible", group = g_RNG)
range_pos = get_table_pos(input.string('Top Right', "Table Position", options = , group = g_RNG))
range_size = get_size(input.string('Normal', "Table Size", options = , group = g_RNG))
var g_DWM = "Day - Week - Month"
dow_labels = input.bool(false, "Day of Week Labels", inline = "DOW", group = g_DWM)
dow_yloc = input.string('Bottom', "", options = , inline = "DOW", group = g_DWM)
dow_xloc = input.string('Midnight', "", options = , inline = "DOW", group = g_DWM)
sep_unlimited = input.bool(true, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_DWM)
show_d_open = input.bool(true, "D Open", inline = "DO", group = g_DWM)
dhl = input.bool(true, "High/Low", inline = "DO", tooltip = "", group = g_DWM)
ds = input.bool(true, "Separators", inline = "DO", tooltip = "Mark where a new day begins", group = g_DWM)
d_color = input.color(color.blue, "", inline = "DO", group = g_DWM)
show_w_open = input.bool(true, "W Open", inline = "WO", group = g_DWM)
whl = input.bool(true, "High/Low", inline = "WO", tooltip = "", group = g_DWM)
ws = input.bool(true, "Separators", inline = "WO", tooltip = "Mark where a new week begins", group = g_DWM)
w_color = input.color(#089981, "", inline = "WO", group = g_DWM)
show_m_open = input.bool(true, "M Open", inline = "MO", group = g_DWM)
mhl = input.bool(true, "High/Low", inline = "MO", tooltip = "", group = g_DWM)
ms = input.bool(true, "Separators", inline = "MO", tooltip = "Mark where a new month begins", group = g_DWM)
m_color = input.color(color.red, "", inline = "MO", group = g_DWM)
htf_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "D0", group = g_DWM))
htf_width = input.int(1, "", inline = "D0", group = g_DWM)
var g_OPEN = "Opening Prices"
open_unlimited = input.bool(true, "Unlimited", tooltip = "Unlimited will show as many of the selected lines as possible. Otherwise, the session drawing limit will be used", group = g_OPEN)
hide_hline = input.bool(true,"Show Opening Price",group = g_OPEN)
hide_lines_h = input.timeframe("60","Hide Above Time Frame",group = g_OPEN)
use_h1 = input.bool(true, "", inline = "H1", group = g_OPEN)
h1_text = input.string("00:00", "", inline = "H1", group = g_OPEN)
h1 = input.session("0000-0001", "", inline = "H1", group = g_OPEN)
h1_color = input.color(#000000, "", inline = "H1", group = g_OPEN)
use_h2 = input.bool(true, "", inline = "H2", group = g_OPEN)
h2_text = input.string("08:30", "", inline = "H2", group = g_OPEN)
h2 = input.session("0830-0831", "", inline = "H2", group = g_OPEN)
h2_color = input.color(#000000, "", inline = "H2", group = g_OPEN)
use_h3 = input.bool(false, "", inline = "H3", group = g_OPEN)
h3_text = input.string("10:00", "", inline = "H3", group = g_OPEN)
h3 = input.session("1000-1001", "", inline = "H3", group = g_OPEN)
h3_color = input.color(#000000, "", inline = "H3", group = g_OPEN)
use_h4 = input.bool(false, "", inline = "H4", group = g_OPEN)
h4_text = input.string("14:00", "", inline = "H4", group = g_OPEN)
h4 = input.session("1400-1401", "", inline = "H4", group = g_OPEN)
h4_color = input.color(#000000, "", inline = "H4", group = g_OPEN)
hz_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "H0", group = g_OPEN))
hz_width = input.int(1, "", inline = "H0", group = g_OPEN)
var g_VERTICAL = "Timestamps"
hide_vline = input.bool(true,"Show Timestamp",group = g_VERTICAL)
hide_lines_v = input.timeframe("60","Hide Above Time Frame",group = g_VERTICAL)
use_v1 = input.bool(true, "", inline = "V1", group = g_VERTICAL)
v1 = input.session("0000-0001", "", inline = "V1", group = g_VERTICAL)
v1_color = input.color(#000000, "", inline = "V1", group = g_VERTICAL)
use_v2 = input.bool(false, "", inline = "V2", group = g_VERTICAL)
v2 = input.session("0800-0801", "", inline = "V2", group = g_VERTICAL)
v2_color = input.color(#000000, "", inline = "V2", group = g_VERTICAL)
use_v3 = input.bool(false, "", inline = "V3", group = g_VERTICAL)
v3 = input.session("1000-1001", "", inline = "V3", group = g_VERTICAL)
v3_color = input.color(#000000, "", inline = "V3", group = g_VERTICAL)
use_v4 = input.bool(false, "", inline = "V4", group = g_VERTICAL)
v4 = input.session("1200-1201", "", inline = "V4", group = g_VERTICAL)
v4_color = input.color(#000000, "", inline = "V4", group = g_VERTICAL)
vl_style = get_line_type(input.string(defval = 'Dotted', title = "Style", options = , inline = "V0", group = g_VERTICAL))
vl_width = input.int(1, "", inline = "V0", group = g_VERTICAL)
// ---------------------------------------- Inputs --------------------------------------------------
// ---------------------------------------- Variables & Constants --------------------------------------------------
type kz
string _title
box _box
line _hi_line
line _md_line
line _lo_line
label _hi_label
label _lo_label
bool _hi_valid
bool _md_valid
bool _lo_valid
float _range_store
float _range_current
type hz
line LN
label LB
bool CO
type dwm_hl
line hi_line
line lo_line
label hi_label
label lo_label
type dwm_info
string tf
float o = na
float h = na
float l = na
float ph = na
float pl = na
var as_kz = kz.new(as_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var lo_kz = kz.new(lo_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var na_kz = kz.new(na_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var nl_kz = kz.new(nl_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var np_kz = kz.new(np_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var op_kz = kz.new(op_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var cl_kz = kz.new(cl_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var m1_kz = kz.new(m1_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var m2_kz = kz.new(m2_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var m3_kz = kz.new(m3_txt, array.new_box(), array.new_line(), array.new_line(), array.new_line(), array.new_label(), array.new_label(), array.new_bool(), array.new_bool(), array.new_bool(), array.new_float())
var hz_1 = hz.new(array.new_line(), array.new_label(), array.new_bool())
var hz_2 = hz.new(array.new_line(), array.new_label(), array.new_bool())
var hz_3 = hz.new(array.new_line(), array.new_label(), array.new_bool())
var hz_4 = hz.new(array.new_line(), array.new_label(), array.new_bool())
var d_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var w_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var m_hl = dwm_hl.new(array.new_line(), array.new_line(), array.new_label(), array.new_label())
var d_info = dwm_info.new("D")
var w_info = dwm_info.new("W")
var m_info = dwm_info.new("M")
t_as = not na(time("", asia, gmt_tz))
t_lo = not na(time("", london, gmt_tz))
t_na = not na(time("", nyam, gmt_tz))
t_nl = not na(time("", nylu, gmt_tz))
t_np = not na(time("", nypm, gmt_tz))
t_op = not na(time("", loop, gmt_tz))
t_cl = not na(time("", locl, gmt_tz))
t_m1 = not na(time("", sb1, gmt_tz))
t_m2 = not na(time("", sb2, gmt_tz))
t_m3 = not na(time("", sb3, gmt_tz))
t_co = not na(time("", cutoff, gmt_tz))
t_h1 = not na(time("", h1, gmt_tz))
t_h2 = not na(time("", h2, gmt_tz))
t_h3 = not na(time("", h3, gmt_tz))
t_h4 = not na(time("", h4, gmt_tz))
t_v1 = not na(time("", v1, gmt_tz))
t_v2 = not na(time("", v2, gmt_tz))
t_v3 = not na(time("", v3, gmt_tz))
t_v4 = not na(time("", v4, gmt_tz))
var d_sep_line = array.new_line()
var w_sep_line = array.new_line()
var m_sep_line = array.new_line()
var d_line = array.new_line()
var w_line = array.new_line()
var m_line = array.new_line()
var d_label = array.new_label()
var w_label = array.new_label()
var m_label = array.new_label()
var v1_line = array.new_line()
var v2_line = array.new_line()
var v3_line = array.new_line()
var v4_line = array.new_line()
var transparent = #ffffff00
var ext_current = ext_which == 'Most Recent'
var ext_past = ext_pivots == 'Past Mitigation'
update_dwm_info(dwm_info n) =>
if timeframe.change(n.tf)
n.ph := n.h
n.pl := n.l
n.o := open
n.h := high
n.l := low
else
n.h := math.max(high, n.h)
n.l := math.min(low, n.l)
if dhl or show_d_open
update_dwm_info(d_info)
if whl or show_w_open
update_dwm_info(w_info)
if mhl or show_m_open
update_dwm_info(m_info)
// ---------------------------------------- Variables & Constants --------------------------------------------------
// ---------------------------------------- Functions --------------------------------------------------
get_box_color(color c) =>
result = color.new(c, box_transparency)
get_text_color(color c) =>
result = color.new(c, text_transparency)
// ---------------------------------------- Functions --------------------------------------------------
// ---------------------------------------- Core Logic --------------------------------------------------
dwm_sep(string tf, bool use, line arr, color col) =>
if use
if timeframe.change(tf)
arr.unshift(line.new(bar_index, high*1.0001, bar_index, low, style = htf_style, width = htf_width, extend = extend.both, color = col))
if not sep_unlimited and arr.size() > max_days
arr.pop().delete()
dwm_open(string tf, bool use, line lns, label lbls, dwm_info n, color col) =>
if use
if timeframe.change(tf)
lns.unshift(line.new(time, n.o, time, n.o, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
lbls.unshift(label.new(time, n.o, tf + " OPEN", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size, text_font_family = font_style))
if not sep_unlimited and lns.size() > max_days
lns.pop().delete()
lbls.pop().delete()
else if lns.size() > 0
lns.get(0).set_x2(time)
lbls.get(0).set_x(time)
dwm_hl(string tf, bool use, dwm_hl hl, dwm_info n, color col) =>
if use
if timeframe.change(tf)
hl.hi_line.unshift(line.new(time, n.ph, time, n.ph, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
hl.lo_line.unshift(line.new(time, n.pl, time, n.pl, xloc = xloc.bar_time, style = htf_style, width = htf_width, color = col))
hl.hi_label.unshift(label.new(time, n.ph, "P"+tf+"H", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size, text_font_family = font_style))
hl.lo_label.unshift(label.new(time, n.pl, "P"+tf+"L", xloc = xloc.bar_time, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size, text_font_family = font_style))
if not sep_unlimited and hl.hi_line.size() > max_days
hl.hi_line.pop().delete()
hl.lo_line.pop().delete()
hl.hi_label.pop().delete()
hl.lo_label.pop().delete()
else if hl.hi_line.size() > 0
hl.hi_line.get(0).set_x2(time)
hl.lo_line.get(0).set_x2(time)
hl.hi_label.get(0).set_x(time)
hl.lo_label.get(0).set_x(time)
dwm() =>
//if timeframe.in_seconds() <= hide_lines_sessions *60
if DWM_profile
if D_profile and timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_DO)
// Draw Daily separators, open lines, and high/low lines
dwm_sep("D", ds, d_sep_line, d_color)
dwm_open("D", show_d_open, d_line, d_label, d_info, d_color)
dwm_hl("D", dhl, d_hl, d_info, d_color)
// Draw Weekly and Monthly only if Daily profile allows it
if W_profile and timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_WO)
dwm_sep("W", ws, w_sep_line, w_color)
dwm_open("W", show_w_open, w_line, w_label, w_info, w_color)
dwm_hl("W", whl, w_hl, w_info, w_color)
if M_profile and timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_MO)
dwm_sep("M", ms, m_sep_line, m_color)
dwm_open("M", show_m_open, m_line, m_label, m_info, m_color)
dwm_hl("M", mhl, m_hl, m_info, m_color)
else if W_profile and timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_WO)
// Draw Weekly separators, open lines, and high/low lines
dwm_sep("W", ws, w_sep_line, w_color)
dwm_open("W", show_w_open, w_line, w_label, w_info, w_color)
dwm_hl("W", whl, w_hl, w_info, w_color)
// Draw Monthly only if Weekly profile allows it
if M_profile and timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_MO)
dwm_sep("M", ms, m_sep_line, m_color)
dwm_open("M", show_m_open, m_line, m_label, m_info, m_color)
dwm_hl("M", mhl, m_hl, m_info, m_color)
else if M_profile and timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_MO)
// Draw Monthly separators, open lines, and high/low lines
dwm_sep("M", ms, m_sep_line, m_color)
dwm_open("M", show_m_open, m_line, m_label, m_info, m_color)
dwm_hl("M", mhl, m_hl, m_info, m_color)
vline(bool use, bool t, line arr, color col) =>
if use
if t and not t
arr.unshift(line.new(bar_index, high*1.0001, bar_index, low, style = vl_style, width = vl_width, extend = extend.both, color = col))
vlines() =>
if hide_vline
if timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_v)
vline(use_v1, t_v1, v1_line, v1_color)
vline(use_v2, t_v2, v2_line, v2_color)
vline(use_v3, t_v3, v3_line, v3_color)
vline(use_v4, t_v4, v4_line, v4_color)
hz_line(bool use, bool t, hz hz, string txt, color col) =>
if use
if t and not t
hz.LN.unshift(line.new(bar_index, open, bar_index, open, style = hz_style, width = hz_width, color = col))
hz.LB.unshift(label.new(bar_index, open, txt, style = label.style_label_left, color = transparent, textcolor = txt_color, size = lbl_size, text_font_family = font_style))
array.unshift(hz.CO, false)
if not open_unlimited and hz.LN.size() > max_days
hz.LN.pop().delete()
hz.LB.pop().delete()
hz.CO.pop()
if not t and hz.CO.size() > 0
if not hz.CO.get(0)
hz.LN.get(0).set_x2(bar_index)
hz.LB.get(0).set_x(bar_index)
if (use_cutoff ? t_co : false)
hz.CO.set(0, true)
hz_lines() =>
if hide_hline
if timeframe.in_seconds("") <= timeframe.in_seconds(hide_lines_h)
hz_line(use_h1, t_h1, hz_1, h1_text, h1_color)
hz_line(use_h2, t_h2, hz_2, h2_text, h2_color)
hz_line(use_h3, t_h3, hz_3, h3_text, h3_color)
hz_line(use_h4, t_h4, hz_4, h4_text, h4_color)
del_kz(kz k) =>
if k._box.size() > max_days
k._box.pop().delete()
if k._hi_line.size() > max_days
k._hi_line.pop().delete()
k._lo_line.pop().delete()
k._hi_valid.pop()
k._lo_valid.pop()
if show_midpoints
k._md_line.pop().delete()
k._md_valid.pop()
if k._hi_label.size() > max_days
k._hi_label.pop().delete()
k._lo_label.pop().delete()
adjust_in_kz(kz kz, bool t) =>
if t
kz._box.get(0).set_right(time)
kz._box.get(0).set_top(math.max(kz._box.get(0).get_top(), high))
kz._box.get(0).set_bottom(math.min(kz._box.get(0).get_bottom(), low))
kz._range_current := kz._box.get(0).get_top() - kz._box.get(0).get_bottom()
if show_pivots and kz._hi_line.size() > 0
if high > kz._hi_line.get(0).get_y1()
kz._hi_line.get(0).set_xy1(time, high)
kz._hi_line.get(0).set_xy2(time, high)
if low < kz._lo_line.get(0).get_y1()
kz._lo_line.get(0).set_xy1(time, low)
kz._lo_line.get(0).set_xy2(time, low)
if show_midpoints
kz._md_line.get(0).set_xy1(time, math.avg(kz._hi_line.get(0).get_y2(), kz._lo_line.get(0).get_y2()))
kz._md_line.get(0).set_xy2(time, math.avg(kz._hi_line.get(0).get_y2(), kz._lo_line.get(0).get_y2()))
if show_labels and kz._hi_label.size() > 0
if high > kz._hi_label.get(0).get_y()
kz._hi_label.get(0).set_xy(time, high)
if low < kz._lo_label.get(0).get_y()
kz._lo_label.get(0).set_xy(time, low)
adjust_out_kz(kz kz, bool t) =>
if not t and kz._box.size() > 0
if t
array.unshift(kz._range_store, kz._range_current)
if kz._range_store.size() > range_avg
kz._range_store.pop()
if kz._box.size() > 0 and show_pivots
for i = 0 to kz._box.size() - 1
if not ext_current or (ext_current and i == 0)
if ext_past ? true : (kz._hi_valid.get(i) == true)
kz._hi_line.get(i).set_x2(time)
if high > kz._hi_line.get(i).get_y1() and kz._hi_valid.get(i) == true
if use_alerts and i == 0
alert("Broke "+kz._title+" High", alert.freq_once_per_bar)
kz._hi_valid.set(i, false)
else if (use_cutoff ? t_co : false)
kz._hi_valid.set(i, false)
if ext_past ? true : (kz._lo_valid.get(i) == true)
kz._lo_line.get(i).set_x2(time)
if low < kz._lo_line.get(i).get_y1() and kz._lo_valid.get(i) == true
if use_alerts and i == 0
alert("Broke "+kz._title+" Low", alert.freq_once_per_bar)
kz._lo_valid.set(i, false)
else if (use_cutoff ? t_co : false)
kz._lo_valid.set(i, false)
if show_midpoints
kz._md_line.get(i).set_x2(time)
else
break
manage_kz(kz kz, bool use, bool t, color c, string box_txt, string hi_txt, string lo_txt) =>
if timeframe.in_seconds("") <= timeframe.in_seconds(tf_limit) and use
if t and not t
_c = get_box_color(c)
_t = get_text_color(c)
kz._box.unshift(box.new(time, high, time, low, xloc = xloc.bar_time, border_color = show_kz ? _c : na, bgcolor = show_kz ? _c : na, text = (show_kz and show_kz_text) ? box_txt : na, text_color = _t))
if show_pivots
kz._hi_line.unshift(line.new(time, high, time, high, xloc = xloc.bar_time, style = kzp_style, color = c, width = kzp_width))
kz._lo_line.unshift(line.new(time, low, time, low, xloc = xloc.bar_time, style = kzp_style, color = c, width = kzp_width))
if show_midpoints
kz._md_line.unshift(line.new(time, math.avg(high, low), time, math.avg(high, low), xloc = xloc.bar_time, style = kzm_style, color = c, width = kzm_width))
array.unshift(kz._md_valid, true)
array.unshift(kz._hi_valid, true)
array.unshift(kz._lo_valid, true)
if show_labels
kz._hi_label.unshift(label.new(time, high, hi_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_down, size = lbl_size))
kz._lo_label.unshift(label.new(time, low, lo_txt, xloc = xloc.bar_time, color = transparent, textcolor = txt_color, style = label.style_label_up, size = lbl_size))
del_kz(kz)
adjust_in_kz(kz, t)
adjust_out_kz(kz, t)
manage_kz(as_kz, use_asia, t_as, as_color, as_txt, ash_str, asl_str)
manage_kz(lo_kz, use_london, t_lo, lo_color, lo_txt, loh_str, lol_str)
manage_kz(na_kz, use_nyam, t_na, na_color, na_txt, nah_str, nal_str)
manage_kz(nl_kz, use_nylu, t_nl, nl_color, nl_txt, nlh_str, nll_str)
manage_kz(np_kz, use_nypm, t_np, np_color, np_txt, nph_str, npl_str)
manage_kz(op_kz, use_loop, t_op, op_color, op_txt, oph_str, opl_str)
manage_kz(cl_kz, use_locl, t_cl, cl_color, cl_txt, clh_str, cll_str)
manage_kz(m1_kz, use_sb1, t_m1, m1_color, m1_txt, m1h_str, m1l_str)
manage_kz(m2_kz, use_sb2, t_m2, m2_color, m2_txt, m2h_str, m2l_str)
manage_kz(m3_kz, use_sb3, t_m3, m3_color, m3_txt, m3h_str, m3l_str)
dwm()
vlines()
hz_lines()
new_dow_time = dow_xloc == 'Midday' ? time - timeframe.in_seconds("D") / 2 * 1000 : time
new_day = dayofweek(new_dow_time, gmt_tz) != dayofweek(new_dow_time, gmt_tz)
var dow_top = dow_yloc == 'Top'
var sunday = "SUNDAY"
var monday = "MONDAY"
var tuesday = "TUESDAY"
var wednesday = "WEDNESDAY"
var thursday = "THURSDAY"
var friday = "FRIDAY"
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 1 and new_day, location = dow_top ? location.top : location.bottom, char = "", textcolor = txt_color, text = sunday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 2 and new_day, location = dow_top ? location.top : location.bottom, char = "", textcolor = txt_color, text = monday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 3 and new_day, location = dow_top ? location.top : location.bottom, char = "", textcolor = txt_color, text = tuesday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 4 and new_day, location = dow_top ? location.top : location.bottom, char = "", textcolor = txt_color, text = wednesday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 5 and new_day, location = dow_top ? location.top : location.bottom, char = "", textcolor = txt_color, text = thursday)
plotchar(dow_labels and timeframe.isintraday and dayofweek(new_dow_time, gmt_tz) == 6 and new_day, location = dow_top ? location.top : location.bottom, char = "", textcolor = txt_color, text = friday)
get_min_days_stored() =>
store = array.new_int()
if as_kz._range_store.size() > 0
store.push(as_kz._range_store.size())
if lo_kz._range_store.size() > 0
store.push(lo_kz._range_store.size())
if na_kz._range_store.size() > 0
store.push(na_kz._range_store.size())
if nl_kz._range_store.size() > 0
store.push(nl_kz._range_store.size())
if np_kz._range_store.size() > 0
store.push(np_kz._range_store.size())
if op_kz._range_store.size() > 0
store.push(op_kz._range_store.size())
if cl_kz._range_store.size() > 0
store.push(cl_kz._range_store.size())
if m1_kz._range_store.size() > 0
store.push(m1_kz._range_store.size())
if m2_kz._range_store.size() > 0
store.push(m2_kz._range_store.size())
if m3_kz._range_store.size() > 0
store.push(m3_kz._range_store.size())
result = store.min()
set_table(table tbl, kz kz, int row, string txt, bool use, bool t, color col) =>
if use
table.cell(tbl, 0, row, txt, text_size = range_size, bgcolor = get_box_color(col), text_color = txt_color)
table.cell(tbl, 1, row, str.tostring(kz._range_current), text_size = range_size, bgcolor = t ? get_box_color(col) : na, text_color = txt_color)
if show_range_avg
table.cell(tbl, 2, row, str.tostring(kz._range_store.avg()), text_size = range_size, text_color = txt_color)
if show_range and barstate.islast
var tbl = table.new(range_pos, 10, 10, chart.bg_color, chart.fg_color, 2, chart.fg_color, 1)
table.cell(tbl, 0, 0, "Killzone", text_size = range_size, text_color = txt_color)
table.cell(tbl, 1, 0, "Range", text_size = range_size, text_color = txt_color)
if show_range_avg
table.cell(tbl, 2, 0, "Avg ("+str.tostring(get_min_days_stored())+")", text_size = range_size, text_color = txt_color)
set_table(tbl, as_kz, 1, as_txt, use_asia, t_as, as_color)
set_table(tbl, lo_kz, 2, lo_txt, use_london, t_lo, lo_color)
set_table(tbl, na_kz, 3, na_txt, use_nyam, t_na, na_color)
set_table(tbl, nl_kz, 4, nl_txt, use_nylu, t_nl, nl_color)
set_table(tbl, np_kz, 5, np_txt, use_nypm, t_np, np_color)
set_table(tbl, op_kz, 6, op_txt, use_loop, t_op, op_color)
set_table(tbl, cl_kz, 7, cl_txt, use_locl, t_cl, cl_color)
set_table(tbl, m1_kz, 8, m1_txt, use_sb1, t_m1, m1_color)
set_table(tbl, m2_kz, 9, m2_txt, use_sb2, t_m2, m2_color)
set_table(tbl, m3_kz, 10, m3_txt, use_sb3, t_m3, m3_color)
// ---------------------------------------- Core Logic --------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------------//
// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// ©Mutharasan2
// Prev Published: 608
// Curr Published: 907
//@version=5
//2nd indicator("ICT HTF Candles (fadi)", overlay=true, max_boxes_count = 500, max_lines_count = 500, max_bars_back = 5000)
type Candle
float o
float c
float h
float l
int o_idx
int c_idx
int h_idx
int l_idx
box body
line wick_up
line wick_down
type Trace
line o
line c
line h
line l
label o_l
label c_l
label h_l
label l_l
type Imbalance
box b
int idx
type CandleSettings
bool show
string htf
int max_display
type Settings
int max_sets
color bull_body
color bull_border
color bull_wick
color bear_body
color bear_border
color bear_wick
int offset
int buffer
int htf_buffer
int width
bool trace_show
color trace_o_color
string trace_o_style
int trace_o_size
color trace_c_color
string trace_c_style
int trace_c_size
color trace_h_color
string trace_h_style
int trace_h_size
color trace_l_color
string trace_l_style
int trace_l_size
string trace_anchor
bool label_show
color label_color
string label_size
bool fvg_show
color fvg_color
bool vi_show
color vi_color
bool htf_label_show
color htf_label_color
string htf_label_size
bool htf_timer_show
color htf_timer_color
string htf_timer_size
string level
string liquidity_open_style
string liquidity_claimed_style
color liquidity_open_color
color liquidity_claimed_color
int liquidity_open_size
int liquidity_claimed_size
int max_lines
int extend
type CandleSet
Candle candles
Imbalance imbalances
CandleSettings settings
label tfName
label tfTimer
type Helper
string name = "Helper"
Settings settings = Settings.new()
var CandleSettings SettingsHTF1 = CandleSettings.new()
var CandleSettings SettingsHTF2 = CandleSettings.new()
var CandleSettings SettingsHTF3 = CandleSettings.new()
var CandleSettings SettingsHTF4 = CandleSettings.new()
var CandleSettings SettingsHTF5 = CandleSettings.new()
var CandleSettings SettingsHTF6 = CandleSettings.new()
var Candle candles_1 = array.new(0)
var Candle candles_2 = array.new(0)
var Candle candles_3 = array.new(0)
var Candle candles_4 = array.new(0)
var Candle candles_5 = array.new(0)
var Candle candles_6 = array.new(0)
var Imbalance imbalances_1 = array.new()
var Imbalance imbalances_2 = array.new()
var Imbalance imbalances_3 = array.new()
var Imbalance imbalances_4 = array.new()
var Imbalance imbalances_5 = array.new()
var Imbalance imbalances_6 = array.new()
var CandleSet htf1 = CandleSet.new()
htf1.settings := SettingsHTF1
htf1.candles := candles_1
htf1.imbalances := imbalances_1
var CandleSet htf2 = CandleSet.new()
htf2.settings := SettingsHTF2
htf2.candles := candles_2
htf2.imbalances := imbalances_2
var CandleSet htf3 = CandleSet.new()
htf3.settings := SettingsHTF3
htf3.candles := candles_3
htf3.imbalances := imbalances_3
var CandleSet htf4 = CandleSet.new()
htf4.settings := SettingsHTF4
htf4.candles := candles_4
htf4.imbalances := imbalances_4
var CandleSet htf5 = CandleSet.new()
htf5.settings := SettingsHTF5
htf5.candles := candles_5
htf5.imbalances := imbalances_5
var CandleSet htf6 = CandleSet.new()
htf6.settings := SettingsHTF6
htf6.candles := candles_6
htf6.imbalances := imbalances_6
//+------------------------------------------------------------------------------------------------------------+//
//+--- Settings ---+//
//+------------------------------------------------------------------------------------------------------------+//
htf1.settings.show := input.bool(false, "HTF 1 ", inline="htf1")
htf_1 = input.timeframe("60", "", inline="htf1")
htf1.settings.htf := htf_1
htf1.settings.max_display := input.int(1, "", inline="htf1")
htf2.settings.show := input.bool(false, "HTF 2 ", inline="htf2")
htf_2 = input.timeframe("240", "", inline="htf2")
htf2.settings.htf := htf_2
htf2.settings.max_display := input.int(1, "", inline="htf2")
htf3.settings.show := input.bool(true, "HTF 3 ", inline="htf3")
htf_3 = input.timeframe("1D", "", inline="htf3")
htf3.settings.htf := htf_3
htf3.settings.max_display := input.int(1, "", inline="htf3")
htf4.settings.show := input.bool(true, "HTF 4 ", inline="htf4")
htf_4 = input.timeframe("1W", "", inline="htf4")
htf4.settings.htf := htf_4
htf4.settings.max_display := input.int(1, "", inline="htf4")
htf5.settings.show := input.bool(true, "HTF 5 ", inline="htf5")
htf_5 = input.timeframe("1M", "", inline="htf5")
htf5.settings.htf := htf_5
htf5.settings.max_display := input.int(1, "", inline="htf5")
htf6.settings.show := input.bool(false, "HTF 6 ", inline="htf6")
htf_6 = input.timeframe("3M", "", inline="htf6")
htf6.settings.htf := htf_6
htf6.settings.max_display := input.int(1, "", inline="htf6")
settings.max_sets := input.int(6, "Limit to next HTFs only", minval=1, maxval=6)
settings.bull_body := input.color(color.rgb(76, 175, 80), "Body ", inline="body")
settings.bear_body := input.color(color.rgb(0, 0, 0), "", inline="body")
settings.bull_border := input.color(color.rgb(93, 96, 107), "Borders", inline="borders")
settings.bear_border := input.color(color.rgb(0, 0, 0), "", inline="borders")
settings.bull_wick := input.color(color.rgb(93, 96, 107), "Wick ", inline="wick")
settings.bear_wick := input.color(color.rgb(93, 96, 107), "", inline="wick")
settings.offset := input.int(10, "padding from current candles", minval = 1)
settings.buffer := input.int(1, "space between candles", minval = 1, maxval = 4)
settings.htf_buffer := input.int(10, "space between Higher Timeframes", minval = 1, maxval = 10)
settings.width := input.int(4, "Candle Width", minval = 1, maxval = 10)*2
settings.htf_label_show := input.bool(false, "HTF Label ", inline="HTFlabel")
settings.htf_label_color := input.color(color.rgb(0, 0, 0), "", inline='HTFlabel')
settings.htf_label_size := input.string(size.tiny, "", , inline="HTFlabel")
settings.htf_timer_show := input.bool(false, "Remaining time ", inline="timer")
settings.htf_timer_color := input.color(color.rgb(0, 0, 0), "", inline='timer')
settings.htf_timer_size := input.string(size.tiny, "", , inline="timer")
settings.fvg_show := input.bool(true, "Fair Value Gap ", group="Imbalance", inline="fvg")
settings.fvg_color := input.color(color.new(color.gray, 80), "", inline='fvg', group="Imbalance")
settings.vi_show := input.bool(true, "Volume Imbalance", group="Imbalance", inline="vi")
settings.vi_color := input.color(color.new(color.red, 50), "", inline='vi', group="Imbalance")
settings.trace_show := input.bool(false, "Trace lines", group="trace")
settings.trace_o_color := input.color(color.rgb(0, 0, 0), "Open ", inline='1', group="trace")
settings.trace_o_style := input.string('····', '', options = , inline='1', group="trace")
settings.trace_o_size := input.int(1, '', options = , inline='1', group="trace")
settings.trace_c_color := input.color(color.rgb(0, 0, 0), "Close ", inline='2', group="trace")
settings.trace_c_style := input.string('····', '', options = , inline='2', group="trace")
settings.trace_c_size := input.int(1, '', options = , inline='2', group="trace")
settings.trace_h_color := input.color(color.rgb(0, 0, 0), "High ", inline='3', group="trace")
settings.trace_h_style := input.string('····', '', options = , inline='3', group="trace")
settings.trace_h_size := input.int(1, '', options = , inline='3', group="trace")
settings.trace_l_color := input.color(color.rgb(0, 0, 0), "Low ", inline='4', group="trace")
settings.trace_l_style := input.string('····', '', options = , inline='4', group="trace")
settings.trace_l_size := input.int(1, '', options = , inline='4', group="trace")
settings.trace_anchor := input.string("First Timeframe", "Anchor to", options= , group="trace")
settings.label_show := input.bool(false, "Price Label ", inline="label")
settings.label_color := input.color(color.rgb(0, 0, 0), "", inline='label')
settings.label_size := input.string(size.small, "", , inline="label")
//+------------------------------------------------------------------------------------------------------------+//
//+--- Variables ---+//
//+------------------------------------------------------------------------------------------------------------+//
Helper helper = Helper.new()
var Trace trace = Trace.new()
color color_transparent = #ffffff00
//+------------------------------------------------------------------------------------------------------------+//
//+--- Internal Functions ---+//
//+------------------------------------------------------------------------------------------------------------+//
method LineStyle(Helper helper, string style) =>
helper.name := style
out = switch style
'----' => line.style_dashed
'····' => line.style_dotted
=> line.style_solid
method ValidTimeframe(Helper helper, string HTF) =>
helper.name := HTF
if timeframe.in_seconds(HTF) >= timeframe.in_seconds("D") and timeframe.in_seconds(HTF) > timeframe.in_seconds()
true
else
n1 = timeframe.in_seconds()
n2 = timeframe.in_seconds(HTF)
n3 = n1 % n2
(n1 < n2 and math.round(n2/n1) == n2/n1)
method RemainingTime(Helper helper, string HTF) =>
helper.name := HTF
if barstate.isrealtime
timeRemaining = (time_close(HTF) - timenow)/1000
days = math.floor(timeRemaining / 86400)
hours = math.floor((timeRemaining - (days*86400)) / 3600)
minutes = math.floor((timeRemaining - (days*86400) - (hours*3600))/ 60)
seconds = math.floor(timeRemaining - (days*86400) - (hours*3600) - (minutes*60))
r = str.tostring(seconds, "00")
if minutes > 0 or hours > 0 or days > 0
r := str.tostring(minutes, "00") + ":" + r
if hours > 0 or days > 0
r := str.tostring(hours, "00") + ":" + r
if days > 0
r := str.tostring(days) + "D " + r
r
else
"n/a"
method HTFName(Helper helper, string HTF) =>
helper.name := "HTFName"
formatted = HTF
seconds = timeframe.in_seconds(HTF)
if seconds < 60
formatted := str.tostring(seconds) + "s"
else if (seconds / 60) < 60
formatted := str.tostring((seconds/60)) + "m"
else if (seconds/60/60) < 24
formatted := str.tostring((seconds/60/60)) + "H"
formatted
method HTFEnabled(Helper helper) =>
helper.name := "HTFEnabled"
int enabled =0
enabled += htf1.settings.show ? 1 : 0
enabled += htf2.settings.show ? 1 : 0
enabled += htf3.settings.show ? 1 : 0
enabled += htf4.settings.show ? 1 : 0
enabled += htf5.settings.show ? 1 : 0
enabled += htf6.settings.show ? 1 : 0
int last = math.min(enabled, settings.max_sets)
last
method CandleSetHigh(Helper helper, Candle candles, float h) =>
helper.name := "CandlesSetHigh"
float _h = h
if array.size(candles) > 0
for i = 0 to array.size(candles)-1
Candle c = array.get(candles, i)
if c.h > _h
_h := c.h
_h
method CandlesHigh(Helper helper, Candle candles) =>
helper.name := "CandlesHigh"
h = 0.0
int cnt = 0
int last = helper.HTFEnabled()
if htf1.settings.show and helper.ValidTimeframe(htf1.settings.htf)
h := helper.CandleSetHigh(htf1.candles, h)
cnt += 1
if htf2.settings.show and helper.ValidTimeframe(htf2.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf2.candles, h)
cnt +=1
if htf3.settings.show and helper.ValidTimeframe(htf3.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf3.candles, h)
cnt += 1
if htf4.settings.show and helper.ValidTimeframe(htf4.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf4.candles, h)
cnt += 1
if htf5.settings.show and helper.ValidTimeframe(htf5.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf5.candles, h)
cnt += 1
if htf6.settings.show and helper.ValidTimeframe(htf6.settings.htf) and cnt < last
h := helper.CandleSetHigh(htf6.candles, h)
h
if array.size(candles) > 0
for i = 0 to array.size(candles)-1
Candle c = array.get(candles, i)
if c.h > h
h := c.h
h
method Reorder(CandleSet candleSet, int offset) =>
size = candleSet.candles.size()
if size > 0
for i = size-1 to 0
Candle candle = candleSet.candles.get(i)
t_buffer = offset + ((settings.width+settings.buffer)*(size-i-1))
box.set_left(candle.body, bar_index + t_buffer)
box.set_right(candle.body, bar_index + settings.width + t_buffer)
line.set_x1(candle.wick_up, bar_index+((settings.width)/2) + t_buffer)
line.set_x2(candle.wick_up, bar_index+((settings.width)/2) + t_buffer)
line.set_x1(candle.wick_down, bar_index+((settings.width)/2) + t_buffer)
line.set_x2(candle.wick_down, bar_index+((settings.width)/2) + t_buffer)
candleSet
top = helper.CandlesHigh(candleSet.candles)
left = bar_index + offset + ((settings.width+settings.buffer)*(size-1))/2
if settings.htf_label_show
var label l = candleSet.tfName
string lbl = helper.HTFName(candleSet.settings.htf)
if settings.htf_timer_show
lbl += "\n"
if not na(l)
label.set_xy(l, left, top)
else
l := label.new(left, top, lbl, color=color_transparent, textcolor = settings.htf_label_color, style=label.style_label_down, size = settings.htf_label_size)
if settings.htf_timer_show
var label t = candleSet.tfTimer
string tmr = "(" + helper.RemainingTime(candleSet.settings.htf) + ")"
if not na(t)
label.set_xy(t, left, top)
else
t := label.new(left, top, tmr, color=color_transparent, textcolor = settings.htf_timer_color, style=label.style_label_down, size = settings.htf_timer_size)
candleSet
method FindImbalance(CandleSet candleSet) =>
if barstate.isrealtime or barstate.islast
if candleSet.imbalances.size() > 0
for i = candleSet.imbalances.size()-1 to 0
Imbalance del = candleSet.imbalances.get(i)
box.delete(del.b)
candleSet.imbalances.pop()
if candleSet.candles.size() > 3 and settings.fvg_show
for i = 1 to candleSet.candles.size() -3
candle1 = candleSet.candles.get(i)
candle2 = candleSet.candles.get(i+2)
candle3 = candleSet.candles.get(i+1)
if (candle1.l > candle2.h and math.min(candle1.o, candle1.c) > math.max(candle2.o, candle2.c))
Imbalance imb = Imbalance.new()
imb.b := box.new(box.get_left(candle2.body), candle2.h, box.get_right(candle1.body), candle1.l, bgcolor=settings.fvg_color, border_color = color_transparent, xloc=xloc.bar_index)
candleSet.imbalances.push(imb)
if (candle1.h < candle2.l and math.max(candle1.o, candle1.c) < math.min(candle2.o, candle2.c))
Imbalance imb = Imbalance.new()
imb.b := box.new(box.get_right(candle1.body), candle1.h, box.get_left(candle2.body), candle2.l, bgcolor=settings.fvg_color, border_color = color_transparent)
candleSet.imbalances.push(imb)
box temp = box.copy(candle3.body)
box.delete(candle3.body)
candle3.body := temp
if candleSet.candles.size() > 2 and settings.vi_show
for i = 1 to candleSet.candles.size() -2
candle1 = candleSet.candles.get(i)
candle2 = candleSet.candles.get(i+1)
if (candle1.l < candle2.h and math.min(candle1.o, candle1.c) > math.max(candle2.o, candle2.c))
Imbalance imb = Imbalance.new()
imb.b := box.new(box.get_left(candle2.body), math.min(candle1.o, candle1.c), box.get_right(candle1.body), math.max(candle2.o, candle2.c), bgcolor=settings.vi_color, border_color = color_transparent)
candleSet.imbalances.push(imb)
if (candle1.h > candle2.l and math.max(candle1.o, candle1.c) < math.min(candle2.o, candle2.c))
Imbalance imb = Imbalance.new()
imb.b := box.new(box.get_right(candle1.body), math.min(candle2.o, candle2.c), box.get_left(candle2.body), math.max(candle1.o, candle1.c), bgcolor=settings.vi_color, border_color = color_transparent)
candleSet.imbalances.push(imb)
candleSet
method Monitor(CandleSet candleSet) =>
HTFBarTime = time(candleSet.settings.htf)
isNewHTFCandle = ta.change(HTFBarTime)
if isNewHTFCandle
Candle candle = Candle.new()
candle.o := open
candle.c := close
candle.h := high
candle.l := low
candle.o_idx := bar_index
candle.c_idx := bar_index
candle.h_idx := bar_index
candle.l_idx := bar_index
bull = candle.c > candle.o
candle.body := box.new(bar_index, math.max(candle.o, candle.c), bar_index+2, math.min(candle.o, candle.c), bull ? settings.bull_border : settings.bear_border, 1, bgcolor = bull ? settings.bull_body : settings.bear_body)
candle.wick_up := line.new(bar_index+1, candle.h, bar_index, math.max(candle.o, candle.c), color=bull ? settings.bull_wick : settings.bear_wick)
candle.wick_down := line.new(bar_index+1, math.min(candle.o, candle.c), bar_index, candle.l, color=bull ? settings.bull_wick : settings.bear_wick)
candleSet.candles.unshift(candle)
if candleSet.candles.size() > candleSet.settings.max_display
Candle delCandle = array.pop(candleSet.candles)
box.delete(delCandle.body)
line.delete(delCandle.wick_up)
line.delete(delCandle.wick_down)
candleSet
method Update(CandleSet candleSet, int offset, bool showTrace) =>
if candleSet.candles.size() > 0
Candle candle = candleSet.candles.first()
candle.h_idx := high > candle.h ? bar_index : candle.h_idx
candle.h := high > candle.h ? high : candle.h
candle.l_idx := low < candle.l ? bar_index : candle.l_idx
candle.l := low < candle.l ? low : candle.l
candle.c := close
candle.c_idx := bar_index
bull = candle.c > candle.o
box.set_top(candle.body, candle.o)
box.set_bottom(candle.body, candle.c)
box.set_bgcolor(candle.body, bull ? settings.bull_body : settings.bear_body)
box.set_border_color(candle.body, bull ? settings.bull_border : settings.bear_border)
line.set_color(candle.wick_up, bull ? settings.bull_wick : settings.bear_wick)
line.set_color(candle.wick_down, bull ? settings.bull_wick : settings.bear_wick)
line.set_y1(candle.wick_up, candle.h)
line.set_y2(candle.wick_up, math.max(candle.o, candle.c))
line.set_y1(candle.wick_down, candle.l)
line.set_y2(candle.wick_down, math.min(candle.o, candle.c))
if barstate.isrealtime or barstate.islast
candleSet.Reorder(offset)
if settings.trace_show and showTrace
if bar_index - candle.o_idx < 5000
if na(trace.o)
trace.o := line.new(candle.o_idx, candle.o, box.get_left(candle.body), candle.o, xloc= xloc.bar_index, color=settings.trace_o_color, style= helper.LineStyle(settings.trace_o_style), width=settings.trace_o_size)
else
line.set_xy1(trace.o, candle.o_idx, candle.o)
line.set_xy2(trace.o, box.get_left(candle.body), candle.o)
if settings.label_show
if na(trace.o_l)
trace.o_l := label.new(box.get_right(candle.body), candle.o, str.tostring(candle.o), textalign = text.align_center, style=label.style_label_left, size=settings.label_size, color=color_transparent, textcolor=settings.label_color)
else
label.set_xy(trace.o_l, box.get_right(candle.body), candle.o)
label.set_text(trace.o_l, str.tostring(candle.o))
if bar_index - candle.c_idx < 5000
if na(trace.c)
trace.c := line.new(candle.c_idx, candle.c, box.get_left(candle.body), candle.c, xloc= xloc.bar_index, color=settings.trace_c_color, style=helper.LineStyle(settings.trace_c_style), width=settings.trace_c_size)
else
line.set_xy1(trace.c, candle.c_idx, candle.c)
line.set_xy2(trace.c, box.get_left(candle.body), candle.c)
if settings.label_show
if na(trace.c_l)
trace.c_l := label.new(box.get_right(candle.body), candle.c, str.tostring(candle.c), textalign = text.align_center, style=label.style_label_left, size=settings.label_size, color=color_transparent, textcolor=settings.label_color)
else
label.set_xy(trace.c_l, box.get_right(candle.body), candle.c)
label.set_text(trace.c_l, str.tostring(candle.c))
if bar_index - candle.h_idx < 5000
if na(trace.h)
trace.h := line.new(candle.h_idx, candle.h, line.get_x1(candle.wick_up), candle.h, xloc= xloc.bar_index, color=settings.trace_h_color, style=helper.LineStyle(settings.trace_h_style), width=settings.trace_h_size)
else
line.set_xy1(trace.h, candle.h_idx, candle.h)
line.set_xy2(trace.h, line.get_x1(candle.wick_up), candle.h)
if settings.label_show
if na(trace.h_l)
trace.h_l := label.new(box.get_right(candle.body), candle.h, str.tostring(candle.h), textalign = text.align_center, style=label.style_label_left, size=settings.label_size, color=color_transparent, textcolor=settings.label_color)
else
label.set_xy(trace.h_l, box.get_right(candle.body), candle.h)
label.set_text(trace.h_l, str.tostring(candle.o))
if bar_index - candle.l_idx < 5000
if na(trace.l)
trace.l := line.new(candle.l_idx, candle.l, line.get_x1(candle.wick_down), candle.l, xloc= xloc.bar_index, color=settings.trace_l_color, style=helper.LineStyle(settings.trace_l_style), width=settings.trace_l_size)
else
line.set_xy1(trace.l, candle.l_idx, candle.l)
line.set_xy2(trace.l, line.get_x1(candle.wick_down), candle.l)
if settings.label_show
if na(trace.l_l)
trace.l_l := label.new(box.get_right(candle.body), candle.l, str.tostring(candle.l), textalign = text.align_center, style=label.style_label_left, size=settings.label_size, color=color_transparent, textcolor=settings.label_color)
else
label.set_xy(trace.l_l, box.get_right(candle.body), candle.l)
label.set_text(trace.l_l, str.tostring(candle.o))
candleSet
int cnt = 0
int last = helper.HTFEnabled()
int offset = settings.offset
if htf1.settings.show and helper.ValidTimeframe(htf1.settings.htf)
bool showTrace = false
if settings.trace_anchor == "First Timeframe"
showTrace := true
if settings.trace_anchor == "Last Timeframe" and settings.max_sets == 1
showTrace := true
htf1.Monitor().Update(offset, showTrace).FindImbalance()
cnt +=1
offset += cnt > 0 ? (htf1.candles.size() * settings.width) + (htf1.candles.size() > 0 ? htf1.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf2.settings.show and helper.ValidTimeframe(htf2.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf2.Monitor().Update(offset, showTrace).FindImbalance()
cnt+=1
offset += cnt > 0 ? (htf2.candles.size() * settings.width) + (htf2.candles.size() > 0 ? htf2.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf3.settings.show and helper.ValidTimeframe(htf3.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf3.Monitor().Update(offset, showTrace).FindImbalance()
cnt+=1
offset += cnt > 0 ? (htf3.candles.size() * settings.width) + (htf3.candles.size() > 0 ? htf3.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf4.settings.show and helper.ValidTimeframe(htf4.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf4.Monitor().Update(offset, showTrace).FindImbalance()
cnt+=1
offset += cnt > 0 ? (htf4.candles.size() * settings.width) + (htf4.candles.size() > 0 ? htf4.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf5.settings.show and helper.ValidTimeframe(htf5.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe" and cnt == last-1
showTrace := true
htf5.Monitor().Update(offset, showTrace).FindImbalance()
cnt+=1
offset += cnt > 0 ? (htf5.candles.size() * settings.width) + (htf5.candles.size() > 0 ? htf5.candles.size()-1 * settings.buffer : 0) + settings.htf_buffer : 0
if htf6.settings.show and helper.ValidTimeframe(htf6.settings.htf) and cnt < last
bool showTrace = false
if settings.trace_anchor == "First Timeframe" and cnt == 0
showTrace := true
if settings.trace_anchor == "Last Timeframe"
showTrace := true
htf6.Monitor().Update(offset, showTrace).FindImbalance()
//------------------------------------------------------------------------------------------------//
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// ©Mutharasan12
//@version=5
//indicator("Notes, Watermark",overlay = true)
// STICKY NOTES #BEGIN --------------------------------------------------------------------------------------------------------------------------------------------------------//
var StickyNote_settings = "STICKY NOTES --------------------------------------------------"
showStickyNotes = input.bool(false, "Show Sticky Notes?", group = StickyNote_settings)
if showStickyNotes
stickynote01 = input.text_area("Your Note Here","NOTES",group = StickyNote_settings)
tl1 = input.string("top", title = "Sticky Note Position (Vertical)", options = , group = StickyNote_settings)
tl2 = input.string("right", title = "Sticky Note Position (Horizontal)", options = , group = StickyNote_settings)
font_size = input.string("Normal", title = "Sticky Note Text Size", options = , group = StickyNote_settings)
font_type = input.string("Default", title = "Font Type", options = , group = StickyNote_settings)
font_color = input.color(color.rgb(0,0,0,0), title = "Note Color", inline = 'nc', group = StickyNote_settings)
note_color = input.color(color (color.rgb(0,0,0,100)), title = "Note Background", inline='nc', group = StickyNote_settings)
selected_font = font_type == "Default" ? font.family_default : font.family_monospace
selected_size = font_size == "Auto" ? size.auto : font_size == "Huge" ? size.huge : font_size == "Large" ? size.large : font_size == "Normal" ? size.normal : font_size == "Small" ? size.small : font_size == "Tiny" ? size.tiny : na
var table t1 = table.new(tl1 + "_" + tl2, 1, 10)
if barstate.islast
if not na(stickynote01) and stickynote01 != ""
table.cell(t1,0,0, text = stickynote01 , bgcolor = note_color, text_color = font_color, text_halign = text.align_left, text_size = selected_size, text_font_family = selected_font)
// STICKY NOTES #END ----------------------------------------------------------------------------------------------------------------------------------------------------------//
// WATERMARK #BEGIN --
Argentum Flag [AGP] Ver.2.5Central Purpose and Concept
The Argentum Flag script is a multifunctional tool that integrates and visualizes multiple key indicators to provide a detailed and unified perspective of the market. The core concept is to analyze price from different angles—volatility, volume, and momentum—to identify confluences and patterns that may be difficult to see with separate indicators. This "mashup" is not a simple fusion of indicators, but a strategic combination of tools that complement each other to offer a comprehensive view of asset behavior.
Components and Their Functionality
This script combines and visualizes the following elements:
EMA Percentage Bands (EMA Bands):
Uses an Exponential Moving Average (EMA) as a baseline.
Calculates and draws several volatility bands that deviate from the central EMA by fixed percentages (0.47%, 0.94%, 2.36%). These bands are inspired by Fibonacci ratios and the cyclical nature of the market.
The bands are colored with a dynamic gradient that reflects the current state of volatility.
Utility: These bands act as dynamic support and resistance areas. The price entering or exiting these zones can indicate a change in volatility or a possible exhaustion of the movement.
Volatility Signals (Vortex & Prime Signals):
The script generates visual signals when the price stays outside the volatility bands for a specific number of bars.
Vortex Signals (diamond ⍲): Appear when the price crosses and stays outside the Prime bands, suggesting a high volatility or a possible continuation of the trend.
Exit/Entry Signals (circle ⌾): Are activated when the price stays outside the Vortex bands, indicating an extreme extension of volatility. These can be interpreted as potential reversal or profit-taking zones.
Utility: They help traders quickly identify moments of high and low volatility and potential turning points in price action.
Volume Analysis (Volume Bar Colors):
The script changes the color of the bars based on the relationship between the current volume and the average volume over a 50-bar period.
Utility: This feature allows the trader to immediately visualize the strength behind a price movement. For example, a bullish candle with "extreme" volume suggests strong buying interest, while a bearish candle with "low" volume could indicate a weak correction.
Summary Tables (Dashboard):
EMA-Fibo Table: Displays the values of 12 EMAs based on the Fibonacci sequence (5, 8, 13, 21...) in an easy-to-access table. The background color of each value indicates if the current price is above (bullish) or below (bearish) that EMA.
Multi-Timeframe RSI Table: Displays the Relative Strength Index (RSI) values across multiple timeframes (from 1 minute to monthly). The text color changes to highlight if the RSI is in overbought (orange) or oversold (white) areas, according to the established levels.
Utility: These tables condense a large amount of data into a simple format, allowing traders to perform a quick, multi-timeframe market analysis without constantly switching charts.
How to Use the Script
This script is a contextual analysis tool that works best when its different components are combined. It is not a "buy and sell signal" system on its own, but a tool for informed decision-making.
Trend Identification: Use the EMA table to see the general trend direction across different timeframes. A price above most of the EMAs in the table suggests a bullish bias.
Volatility Reading: Observe the EMA bands. If the price stays within the bands, volatility is low. A strong move that breaks out of the bands, accompanied by an "extreme" volume color (blue), suggests strong momentum that could continue.
Momentum Analysis: Use the RSI table to confirm movements. An overbought 15m RSI could support a reversal signal from the Vortex bands, while a 1D RSI in a neutral zone may indicate that the main trend has not changed.
Signal Confirmation: Visual signals (diamond and circle) should not be used in isolation. They must be confirmed by volume analysis and dashboard readings. For example, an "Exit Signal" (circle) with low volume may be less reliable than one with high volume and a clear reversal candle.
Disclaimer
This script is for informational and educational purposes only. It is not financial advice, nor is it a recommendation to buy or sell any financial instrument. All trading involves risk, and past performance is not indicative of future results. The user is solely responsible for their own trading decisions.
Relative Strength and MomentumRelative Strength and Momentum Indicator
Unlock deeper market insights with the Relative Strength and Momentum Indicator—a powerful tool designed to help traders and investors identify the strongest stocks and sectors based on relative performance. This custom indicator displays essential information on relative strength and momentum for up to 15 different symbols, compared against a benchmark index, all within a clear and organized table format.
Key Features:
1. Customizable Inputs: Choose up to 15 symbols to compare, along with a benchmark index, allowing you to tailor the indicator to your trading strategy. The 'Lookback Period' input defines how many weeks of data are analyzed for relative strength and momentum.
2. Relative Strength Calculation: For each selected symbol, the indicator calculates the Relative Strength (RS) against the chosen benchmark. This RS is further refined using an exponential moving average (EMA) to smooth the results, providing a more stable trend overview.
3. Momentum Analysis: Momentum is determined by analyzing the rate of change in relative strength. The indicator calculates a momentum rank for each symbol, based on its relative strength’s improvement or deterioration.
4. Percentile Ranking System: Each symbol is assigned a percentile rank (from 1 to 100) based on its relative strength compared to the others. Similarly, momentum rankings are also assigned from 1 to 100, offering a clear understanding of which assets are outperforming or underperforming.
5. Visual Indicators:
a. Green: Signals improving or stable relative strength and momentum.
b. Red: Indicates declining relative strength or momentum.
c. Aqua: Highlights symbols performing well on both relative strength and momentum—ideal candidates for further analysis.
6. Two Clear Tables:
a. Relative Strength Rank Table: Displays weekly rankings of relative strength for each symbol.
b. Momentum Table: Shows momentum trends, helping you identify which symbols are gaining or losing strength.
7. Color-Coded for Easy Analysis: The tables are color-coded to make analysis quick and straightforward. A green color means the symbol is performing well in terms of relative strength or momentum, while red indicates weaker performance. Aqua marks symbols that are excelling in both areas.
Use Case:
a. Sector Comparison: Identify which sectors or indexes are showing both relative strength and momentum to pick high-potential stocks. This allows you to align with broader market trends for improved trade entries.
b. Stock Selection: Quickly compare symbols within the same sector to find the stronger performers.
ADR levels+// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © notprofessorgreen
//@version=5
indicator("ADR levels", shorttitle = 'ADR', overlay=true, max_bars_back=5000, max_lines_count=500)
// Error catching
if (timeframe.in_seconds() >= timeframe.in_seconds('D'))
runtime.error('Timeframe cannot be greater than Daily')
// Inputs
adr_days = input.int(10, title = 'Days', maxval=250, minval = 1)
std_x = input.float(1.0, "Scale Factor")
width = input.int(1, "Line Width")
// ADR line inputs
adr_color = input.color(color.gray, "ADR Color")
adr_style = input.string("solid", "ADR Style", options= )
// Standard deviation inputs
std_dev_0_5 = input.float(0.5, "Std Dev 1 Multiplier", minval=0.1, maxval=5.0)
std_0_5_show = input.bool(true, "Show Std Dev 1", inline="std1")
std_0_5_color = input.color(color.gray, "Std Dev 1 Color", inline="std1")
std_0_5_style = input.string("dotted", "Std Dev 1 Style", options= , inline="std1")
std_dev_1 = input.float(1.0, "Std Dev 2 Multiplier", minval=0.1, maxval=5.0)
std_1_show = input.bool(true, "Show Std Dev 2", inline="std2")
std_1_color = input.color(color.gray, "Std Dev 2 Color", inline="std2")
std_1_style = input.string("dotted", "Std Dev 2 Style", options= , inline="std2")
std_dev_2 = input.float(2.0, "Std Dev 3 Multiplier", minval=0.1, maxval=5.0)
std_2_show = input.bool(true, "Show Std Dev 3", inline="std3")
std_2_color = input.color(color.gray, "Std Dev 3 Color", inline="std3")
std_2_style = input.string("dotted", "Std Dev 3 Style", options= , inline="std3")
// Fibonacci inputs
fib_1_level = input.float(0.3, "Fib Level 1", minval=0, maxval=2.0)
fib_1_show = input.bool(true, "Show Fib 1", inline="fib1")
fib_1_color = input.color(color.blue, "Fib 1 Color", inline="fib1")
fib_1_style = input.string("dashed", "Fib 1 Style", options= , inline="fib1")
fib_2_level = input.float(0.5, "Fib Level 2", minval=0, maxval=2.0)
fib_2_show = input.bool(true, "Show Fib 2", inline="fib2")
fib_2_color = input.color(color.blue, "Fib 2 Color", inline="fib2")
fib_2_style = input.string("dashed", "Fib 2 Style", options= , inline="fib2")
fib_3_level = input.float(0.7, "Fib Level 3", minval=0, maxval=2.0)
fib_3_show = input.bool(true, "Show Fib 3", inline="fib3")
fib_3_color = input.color(color.blue, "Fib 3 Color", inline="fib3")
fib_3_style = input.string("dashed", "Fib 3 Style", options= , inline="fib3")
show_labels = input.bool(true, "Show Labels")
// Stats table inputs
show_stats = input.bool(true, "Show Table")
sample_size = input.bool(true, "Show Sample Sizes")
tbl_loc = input.string('Bottom Right', "Table", options = )
tbl_size = input.string('Tiny', "", options = )
rch_color = input.color(color.rgb(3, 131, 99, 70), "Reached ")
csd_color = input.color(color.rgb(127, 1, 185, 70), "Closed Through ")
// Function to convert style string to line style
get_line_style(string style) =>
switch style
"solid" => line.style_solid
"dashed" => line.style_dashed
"dotted" => line.style_dotted
// Variables
reset = session.islastbar_regular
var float track_highs = 0.00
var float track_lows = 0.00
var float today_adr = 0.00
var adrs = array.new_float(adr_days, 0.00)
var line adr_pos = na
var line adr_neg = na
var line fib_1_pos = na
var line fib_1_neg = na
var line fib_2_pos = na
var line fib_2_neg = na
var line fib_3_pos = na
var line fib_3_neg = na
var line std_0_5_pos = na
var line std_0_5_neg = na
var line std_1_pos = na
var line std_1_neg = na
var line std_2_pos = na
var line std_2_neg = na
var label fib_1_pos_lbl = na
var label fib_1_neg_lbl = na
var label fib_2_pos_lbl = na
var label fib_2_neg_lbl = na
var label fib_3_pos_lbl = na
var label fib_3_neg_lbl = na
var label adr_pos_lbl = na
var label adr_neg_lbl = na
var label std_0_5_pos_lbl = na
var label std_0_5_neg_lbl = na
var label std_1_pos_lbl = na
var label std_1_neg_lbl = na
var label std_2_pos_lbl = na
var label std_2_neg_lbl = na
// ADR calculation
track_highs := reset ? high : math.max(high, track_highs )
track_lows := reset ? low : math.min(low, track_lows )
if reset
array.unshift(adrs, math.round_to_mintick(track_highs - track_lows ))
if array.size(adrs) > adr_days
array.pop(adrs)
today_adr := math.round_to_mintick(array.avg(adrs))
// Delete previous lines and labels
line.delete(adr_pos )
line.delete(adr_neg )
line.delete(fib_1_pos )
line.delete(fib_1_neg )
line.delete(fib_2_pos )
line.delete(fib_2_neg )
line.delete(fib_3_pos )
line.delete(fib_3_neg )
line.delete(std_0_5_pos )
line.delete(std_0_5_neg )
line.delete(std_1_pos )
line.delete(std_1_neg )
line.delete(std_2_pos )
line.delete(std_2_neg )
label.delete(fib_1_pos_lbl )
label.delete(fib_1_neg_lbl )
label.delete(fib_2_pos_lbl )
label.delete(fib_2_neg_lbl )
label.delete(fib_3_pos_lbl )
label.delete(fib_3_neg_lbl )
label.delete(adr_pos_lbl )
label.delete(adr_neg_lbl )
label.delete(std_0_5_pos_lbl )
label.delete(std_0_5_neg_lbl )
label.delete(std_1_pos_lbl )
label.delete(std_1_neg_lbl )
label.delete(std_2_pos_lbl )
label.delete(std_2_neg_lbl )
// Draw ADR lines
adr_pos := line.new(bar_index, open + today_adr, bar_index+50, open + today_adr,
width=width, color=adr_color, style=get_line_style(adr_style))
adr_neg := line.new(bar_index, open - today_adr, bar_index+50, open - today_adr,
width=width, color=adr_color, style=get_line_style(adr_style))
// Draw ADR labels
if show_labels
adr_pos_lbl := label.new(bar_index+50, open + today_adr, "ADR High (" + str.tostring(adr_days) + "D)",
xloc=xloc.bar_index, textalign=text.align_left, textcolor=adr_color, color=color.new(color.blue, 90), style=label.style_none)
adr_neg_lbl := label.new(bar_index+50, open - today_adr, "ADR Low (" + str.tostring(adr_days) + "D)",
xloc=xloc.bar_index, textalign=text.align_left, textcolor=adr_color, color=color.new(color.red, 90), style=label.style_none)
// Calculate deviations
var float half_dev = na
var float one_dev = na
var float two_dev = na
half_dev := today_adr * std_dev_0_5
one_dev := today_adr * std_dev_1
two_dev := today_adr * std_dev_2
// Draw standard deviation lines (with show/hide options)
if std_0_5_show
std_0_5_pos := line.new(bar_index, (open + today_adr) + half_dev, bar_index+50, (open + today_adr) + half_dev,
width=width, color=std_0_5_color, style=get_line_style(std_0_5_style))
std_0_5_neg := line.new(bar_index, (open - today_adr) - half_dev, bar_index+50, (open - today_adr) - half_dev,
width=width, color=std_0_5_color, style=get_line_style(std_0_5_style))
if show_labels
std_0_5_pos_lbl := label.new(bar_index+50, (open + today_adr) + half_dev, "Std " + str.tostring(std_dev_0_5),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=std_0_5_color, color=color.new(#000000,100), style=label.style_none)
std_0_5_neg_lbl := label.new(bar_index+50, (open - today_adr) - half_dev, "Std -" + str.tostring(std_dev_0_5),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=std_0_5_color, color=color.new(#000000,100), style=label.style_none)
if std_1_show
std_1_pos := line.new(bar_index, (open + today_adr) + one_dev, bar_index+50, (open + today_adr) + one_dev,
width=width, color=std_1_color, style=get_line_style(std_1_style))
std_1_neg := line.new(bar_index, (open - today_adr) - one_dev, bar_index+50, (open - today_adr) - one_dev,
width=width, color=std_1_color, style=get_line_style(std_1_style))
if show_labels
std_1_pos_lbl := label.new(bar_index+50, (open + today_adr) + one_dev, "Std " + str.tostring(std_dev_1),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=std_1_color, color=color.new(#000000,100), style=label.style_none)
std_1_neg_lbl := label.new(bar_index+50, (open - today_adr) - one_dev, "Std -" + str.tostring(std_dev_1),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=std_1_color, color=color.new(#000000,100), style=label.style_none)
if std_2_show
std_2_pos := line.new(bar_index, (open + today_adr) + two_dev, bar_index+50, (open + today_adr) + two_dev,
width=width, color=std_2_color, style=get_line_style(std_2_style))
std_2_neg := line.new(bar_index, (open - today_adr) - two_dev, bar_index+50, (open - today_adr) - two_dev,
width=width, color=std_2_color, style=get_line_style(std_2_style))
if show_labels
std_2_pos_lbl := label.new(bar_index+50, (open + today_adr) + two_dev, "Std " + str.tostring(std_dev_2),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=std_2_color, color=color.new(#000000,100), style=label.style_none)
std_2_neg_lbl := label.new(bar_index+50, (open - today_adr) - two_dev, "Std -" + str.tostring(std_dev_2),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=std_2_color, color=color.new(#000000,100), style=label.style_none)
// Draw Fibonacci lines
if fib_1_show
fib_1_pos := line.new(bar_index, open + today_adr * fib_1_level, bar_index+50, open + today_adr * fib_1_level,
width=width, color=fib_1_color, style=get_line_style(fib_1_style))
fib_1_neg := line.new(bar_index, open - today_adr * fib_1_level, bar_index+50, open - today_adr * fib_1_level,
width=width, color=fib_1_color, style=get_line_style(fib_1_style))
if show_labels
fib_1_pos_lbl := label.new(bar_index+50, open + today_adr * fib_1_level, "Fib " + str.tostring(fib_1_level),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=fib_1_color, color=color.new(#000000,100), style=label.style_none)
fib_1_neg_lbl := label.new(bar_index+50, open - today_adr * fib_1_level, "Fib -" + str.tostring(fib_1_level),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=fib_1_color, color=color.new(#000000,100), style=label.style_none)
if fib_2_show
fib_2_pos := line.new(bar_index, open + today_adr * fib_2_level, bar_index+50, open + today_adr * fib_2_level,
width=width, color=fib_2_color, style=get_line_style(fib_2_style))
fib_2_neg := line.new(bar_index, open - today_adr * fib_2_level, bar_index+50, open - today_adr * fib_2_level,
width=width, color=fib_2_color, style=get_line_style(fib_2_style))
if show_labels
fib_2_pos_lbl := label.new(bar_index+50, open + today_adr * fib_2_level, "Fib " + str.tostring(fib_2_level),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=fib_2_color, color=color.new(#000000,100), style=label.style_none)
fib_2_neg_lbl := label.new(bar_index+50, open - today_adr * fib_2_level, "Fib -" + str.tostring(fib_2_level),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=fib_2_color, color=color.new(#000000,100), style=label.style_none)
if fib_3_show
fib_3_pos := line.new(bar_index, open + today_adr * fib_3_level, bar_index+50, open + today_adr * fib_3_level,
width=width, color=fib_3_color, style=get_line_style(fib_3_style))
fib_3_neg := line.new(bar_index, open - today_adr * fib_3_level, bar_index+50, open - today_adr * fib_3_level,
width=width, color=fib_3_color, style=get_line_style(fib_3_style))
if show_labels
fib_3_pos_lbl := label.new(bar_index+50, open + today_adr * fib_3_level, "Fib " + str.tostring(fib_3_level),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=fib_3_color, color=color.new(#000000,100), style=label.style_none)
fib_3_neg_lbl := label.new(bar_index+50, open - today_adr * fib_3_level, "Fib -" + str.tostring(fib_3_level),
xloc=xloc.bar_index, textalign=text.align_left, textcolor=fib_3_color, color=color.new(#000000,100), style=label.style_none)
else
today_adr := today_adr
line.set_x2(adr_pos, bar_index+50)
line.set_x2(adr_neg, bar_index+50)
if show_labels
label.set_x(adr_pos_lbl, bar_index+50)
label.set_x(adr_neg_lbl, bar_index+50)
if std_0_5_show
line.set_x2(std_0_5_pos, bar_index+50)
line.set_x2(std_0_5_neg, bar_index+50)
if show_labels
label.set_x(std_0_5_pos_lbl, bar_index+50)
label.set_x(std_0_5_neg_lbl, bar_index+50)
if std_1_show
line.set_x2(std_1_pos, bar_index+50)
line.set_x2(std_1_neg, bar_index+50)
if show_labels
label.set_x(std_1_pos_lbl, bar_index+50)
label.set_x(std_1_neg_lbl, bar_index+50)
if std_2_show
line.set_x2(std_2_pos, bar_index+50)
line.set_x2(std_2_neg, bar_index+50)
if show_labels
label.set_x(std_2_pos_lbl, bar_index+50)
label.set_x(std_2_neg_lbl, bar_index+50)
if fib_1_show
line.set_x2(fib_1_pos, bar_index+50)
line.set_x2(fib_1_neg, bar_index+50)
if show_labels
label.set_x(fib_1_pos_lbl, bar_index+50)
label.set_x(fib_1_neg_lbl, bar_index+50)
if fib_2_show
line.set_x2(fib_2_pos, bar_index+50)
line.set_x2(fib_2_neg, bar_index+50)
if show_labels
label.set_x(fib_2_pos_lbl, bar_index+50)
label.set_x(fib_2_neg_lbl, bar_index+50)
if fib_3_show
line.set_x2(fib_3_pos, bar_index+50)
line.set_x2(fib_3_neg, bar_index+50)
if show_labels
label.set_x(fib_3_pos_lbl, bar_index+50)
label.set_x(fib_3_neg_lbl, bar_index+50)
// Stats calculation
var float d_hi = high
var float d_lo = low
var float d_open = open
var float d_range = array.new_float()
var float adr_val = na
var float d_adr_hi = na
var float d_adr_lo = na
type adr_stats
int hit_adr_hi = 0
int hit_adr_lo = 0
int hit_adr_both = 0
int thru_adr_hi = 0
int thru_adr_lo = 0
int hit_fib_1_hi = 0
int hit_fib_1_lo = 0
int hit_fib_2_hi = 0
int hit_fib_2_lo = 0
int hit_fib_3_hi = 0
int hit_fib_3_lo = 0
int hit_std_0_5_hi = 0
int hit_std_0_5_lo = 0
int hit_std_1_hi = 0
int hit_std_1_lo = 0
int hit_std_2_hi = 0
int hit_std_2_lo = 0
int d_count = 0
var adr_sun = adr_stats.new()
var adr_mon = adr_stats.new()
var adr_tue = adr_stats.new()
var adr_wed = adr_stats.new()
var adr_thu = adr_stats.new()
var adr_fri = adr_stats.new()
var adr_sat = adr_stats.new()
if timeframe.change("D")
x = adr_mon
dow = dayofweek(time , "America/New_York")
if dow == dayofweek.tuesday
x := adr_tue
else if dow == dayofweek.wednesday
x := adr_wed
else if dow == dayofweek.thursday
x := adr_thu
else if dow == dayofweek.friday
x := adr_fri
else if dow == dayofweek.saturday
x := adr_sat
else if dow == dayofweek.sunday
x := adr_sun
if not na(adr_val)
x.d_count += 1
if d_hi > d_adr_hi
x.hit_adr_hi += 1
if d_lo < d_adr_lo
x.hit_adr_lo += 1
if d_hi > d_adr_hi and d_lo < d_adr_lo
x.hit_adr_both += 1
if close > d_adr_hi
x.thru_adr_hi += 1
if close < d_adr_lo
x.thru_adr_lo += 1
if fib_1_show
if d_hi > d_open + (adr_val * fib_1_level)
x.hit_fib_1_hi += 1
if d_lo < d_open - (adr_val * fib_1_level)
x.hit_fib_1_lo += 1
if fib_2_show
if d_hi > d_open + (adr_val * fib_2_level)
x.hit_fib_2_hi += 1
if d_lo < d_open - (adr_val * fib_2_level)
x.hit_fib_2_lo += 1
if fib_3_show
if d_hi > d_open + (adr_val * fib_3_level)
x.hit_fib_3_hi += 1
if d_lo < d_open - (adr_val * fib_3_level)
x.hit_fib_3_lo += 1
if std_0_5_show
if d_hi > d_adr_hi + (adr_val * std_dev_0_5)
x.hit_std_0_5_hi += 1
if d_lo < d_adr_lo - (adr_val * std_dev_0_5)
x.hit_std_0_5_lo += 1
if std_1_show
if d_hi > d_adr_hi + (adr_val * std_dev_1)
x.hit_std_1_hi += 1
if d_lo < d_adr_lo - (adr_val * std_dev_1)
x.hit_std_1_lo += 1
if std_2_show
if d_hi > d_adr_hi + (adr_val * std_dev_2)
x.hit_std_2_hi += 1
if d_lo < d_adr_lo - (adr_val * std_dev_2)
x.hit_std_2_lo += 1
if timeframe.change("D")
d_open := open
array.unshift(d_range, d_hi - d_lo)
if array.size(d_range) > adr_days
array.pop(d_range)
if array.size(d_range) == adr_days
adr_val := array.avg(d_range)
d_adr_hi := open + (adr_val*std_x)/2
d_adr_lo := open - (adr_val*std_x)/2
d_hi := high
d_lo := low
else
d_hi := math.max(high, d_hi)
d_lo := math.min(low, d_lo)
// Table functions
get_table_pos(pos) =>
switch pos
"Bottom Center" => position.bottom_center
"Bottom Left" => position.bottom_left
"Bottom Right" => position.bottom_right
"Middle Center" => position.middle_center
"Middle Left" => position.middle_left
"Middle Right" => position.middle_right
"Top Center" => position.top_center
"Top Left" => position.top_left
"Top Right" => position.top_right
var _loc = get_table_pos(tbl_loc)
get_table_size(size) =>
switch size
'Tiny' => size.tiny
'Small' => size.small
'Normal' => size.normal
'Large' => size.large
'Huge' => size.huge
'Auto' => size.auto
var _size = get_table_size(tbl_size)
fmt_sample(s, float pct, int count) =>
str.format("{0,number,percent}", pct) + (sample_size ? " ("+str.tostring(count)+")" : "")
// Draw table
if barstate.islast and show_stats
var tbl = table.new(_loc, 100, 100, chart.bg_color, chart.fg_color, 2, chart.fg_color, 1)
// Column headers (days + empty first cell)
table.cell(tbl, 0, 0, "Level", text_size = _size)
table.cell(tbl, 1, 0, "Mon", bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, 0, "Tue", bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, 0, "Wed", bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, 0, "Thu", bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, 0, "Fri", bgcolor = rch_color, text_size = _size)
// Row headers and data
var row = 1
table.cell(tbl, 0, row, "ADR High", text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_adr_hi / adr_mon.d_count, adr_mon.hit_adr_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_adr_hi / adr_tue.d_count, adr_tue.hit_adr_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_adr_hi / adr_wed.d_count, adr_wed.hit_adr_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_adr_hi / adr_thu.d_count, adr_thu.hit_adr_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_adr_hi / adr_fri.d_count, adr_fri.hit_adr_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "ADR Low", text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_adr_lo / adr_mon.d_count, adr_mon.hit_adr_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_adr_lo / adr_tue.d_count, adr_tue.hit_adr_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_adr_lo / adr_wed.d_count, adr_wed.hit_adr_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_adr_lo / adr_thu.d_count, adr_thu.hit_adr_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_adr_lo / adr_fri.d_count, adr_fri.hit_adr_lo), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "ADR High (Close)", text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.thru_adr_hi / adr_mon.d_count, adr_mon.thru_adr_hi), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.thru_adr_hi / adr_tue.d_count, adr_tue.thru_adr_hi), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.thru_adr_hi / adr_wed.d_count, adr_wed.thru_adr_hi), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.thru_adr_hi / adr_thu.d_count, adr_thu.thru_adr_hi), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.thru_adr_hi / adr_fri.d_count, adr_fri.thru_adr_hi), bgcolor = csd_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "ADR Low (Close)", text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.thru_adr_lo / adr_mon.d_count, adr_mon.thru_adr_lo), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.thru_adr_lo / adr_tue.d_count, adr_tue.thru_adr_lo), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.thru_adr_lo / adr_wed.d_count, adr_wed.thru_adr_lo), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.thru_adr_lo / adr_thu.d_count, adr_thu.thru_adr_lo), bgcolor = csd_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.thru_adr_lo / adr_fri.d_count, adr_fri.thru_adr_lo), bgcolor = csd_color, text_size = _size)
row := row + 1
if fib_1_show
table.cell(tbl, 0, row, "Fib " + str.tostring(fib_1_level), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_fib_1_hi / adr_mon.d_count, adr_mon.hit_fib_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_fib_1_hi / adr_tue.d_count, adr_tue.hit_fib_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_fib_1_hi / adr_wed.d_count, adr_wed.hit_fib_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_fib_1_hi / adr_thu.d_count, adr_thu.hit_fib_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_fib_1_hi / adr_fri.d_count, adr_fri.hit_fib_1_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "Fib -" + str.tostring(fib_1_level), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_fib_1_lo / adr_mon.d_count, adr_mon.hit_fib_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_fib_1_lo / adr_tue.d_count, adr_tue.hit_fib_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_fib_1_lo / adr_wed.d_count, adr_wed.hit_fib_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_fib_1_lo / adr_thu.d_count, adr_thu.hit_fib_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_fib_1_lo / adr_fri.d_count, adr_fri.hit_fib_1_lo), bgcolor = rch_color, text_size = _size)
row := row + 1
if fib_2_show
table.cell(tbl, 0, row, "Fib " + str.tostring(fib_2_level), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_fib_2_hi / adr_mon.d_count, adr_mon.hit_fib_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_fib_2_hi / adr_tue.d_count, adr_tue.hit_fib_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_fib_2_hi / adr_wed.d_count, adr_wed.hit_fib_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_fib_2_hi / adr_thu.d_count, adr_thu.hit_fib_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_fib_2_hi / adr_fri.d_count, adr_fri.hit_fib_2_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "Fib -" + str.tostring(fib_2_level), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_fib_2_lo / adr_mon.d_count, adr_mon.hit_fib_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_fib_2_lo / adr_tue.d_count, adr_tue.hit_fib_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_fib_2_lo / adr_wed.d_count, adr_wed.hit_fib_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_fib_2_lo / adr_thu.d_count, adr_thu.hit_fib_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_fib_2_lo / adr_fri.d_count, adr_fri.hit_fib_2_lo), bgcolor = rch_color, text_size = _size)
row := row + 1
if fib_3_show
table.cell(tbl, 0, row, "Fib " + str.tostring(fib_3_level), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_fib_3_hi / adr_mon.d_count, adr_mon.hit_fib_3_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_fib_3_hi / adr_tue.d_count, adr_tue.hit_fib_3_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_fib_3_hi / adr_wed.d_count, adr_wed.hit_fib_3_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_fib_3_hi / adr_thu.d_count, adr_thu.hit_fib_3_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_fib_3_hi / adr_fri.d_count, adr_fri.hit_fib_3_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "Fib -" + str.tostring(fib_3_level), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_fib_3_lo / adr_mon.d_count, adr_mon.hit_fib_3_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_fib_3_lo / adr_tue.d_count, adr_tue.hit_fib_3_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_fib_3_lo / adr_wed.d_count, adr_wed.hit_fib_3_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_fib_3_lo / adr_thu.d_count, adr_thu.hit_fib_3_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_fib_3_lo / adr_fri.d_count, adr_fri.hit_fib_3_lo), bgcolor = rch_color, text_size = _size)
row := row + 1
if std_0_5_show
table.cell(tbl, 0, row, "Std " + str.tostring(std_dev_0_5), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_std_0_5_hi / adr_mon.d_count, adr_mon.hit_std_0_5_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_std_0_5_hi / adr_tue.d_count, adr_tue.hit_std_0_5_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_std_0_5_hi / adr_wed.d_count, adr_wed.hit_std_0_5_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_std_0_5_hi / adr_thu.d_count, adr_thu.hit_std_0_5_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_std_0_5_hi / adr_fri.d_count, adr_fri.hit_std_0_5_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "Std -" + str.tostring(std_dev_0_5), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_std_0_5_lo / adr_mon.d_count, adr_mon.hit_std_0_5_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_std_0_5_lo / adr_tue.d_count, adr_tue.hit_std_0_5_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_std_0_5_lo / adr_wed.d_count, adr_wed.hit_std_0_5_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_std_0_5_lo / adr_thu.d_count, adr_thu.hit_std_0_5_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_std_0_5_lo / adr_fri.d_count, adr_fri.hit_std_0_5_lo), bgcolor = rch_color, text_size = _size)
row := row + 1
if std_1_show
table.cell(tbl, 0, row, "Std " + str.tostring(std_dev_1), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_std_1_hi / adr_mon.d_count, adr_mon.hit_std_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_std_1_hi / adr_tue.d_count, adr_tue.hit_std_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_std_1_hi / adr_wed.d_count, adr_wed.hit_std_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_std_1_hi / adr_thu.d_count, adr_thu.hit_std_1_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_std_1_hi / adr_fri.d_count, adr_fri.hit_std_1_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "Std -" + str.tostring(std_dev_1), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_std_1_lo / adr_mon.d_count, adr_mon.hit_std_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_std_1_lo / adr_tue.d_count, adr_tue.hit_std_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_std_1_lo / adr_wed.d_count, adr_wed.hit_std_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_std_1_lo / adr_thu.d_count, adr_thu.hit_std_1_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_std_1_lo / adr_fri.d_count, adr_fri.hit_std_1_lo), bgcolor = rch_color, text_size = _size)
row := row + 1
if std_2_show
table.cell(tbl, 0, row, "Std " + str.tostring(std_dev_2), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_std_2_hi / adr_mon.d_count, adr_mon.hit_std_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_std_2_hi / adr_tue.d_count, adr_tue.hit_std_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_std_2_hi / adr_wed.d_count, adr_wed.hit_std_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_std_2_hi / adr_thu.d_count, adr_thu.hit_std_2_hi), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_std_2_hi / adr_fri.d_count, adr_fri.hit_std_2_hi), bgcolor = rch_color, text_size = _size)
row := row + 1
table.cell(tbl, 0, row, "Std -" + str.tostring(std_dev_2), text_size = _size)
table.cell(tbl, 1, row, fmt_sample(adr_mon.d_count, adr_mon.hit_std_2_lo / adr_mon.d_count, adr_mon.hit_std_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 2, row, fmt_sample(adr_tue.d_count, adr_tue.hit_std_2_lo / adr_tue.d_count, adr_tue.hit_std_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 3, row, fmt_sample(adr_wed.d_count, adr_wed.hit_std_2_lo / adr_wed.d_count, adr_wed.hit_std_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 4, row, fmt_sample(adr_thu.d_count, adr_thu.hit_std_2_lo / adr_thu.d_count, adr_thu.hit_std_2_lo), bgcolor = rch_color, text_size = _size)
table.cell(tbl, 5, row, fmt_sample(adr_fri.d_count, adr_fri.hit_std_2_lo / adr_fri.d_count, adr_fri.hit_std_2_lo), bgcolor = rch_color, text_size = _size)
analytics_tablesLibrary "analytics_tables"
📝 Description
This library provides the implementation of several performance-related statistics and metrics, presented in the form of tables.
The metrics shown in the afforementioned tables where developed during the past years of my in-depth analalysis of various strategies in an atempt to reason about the performance of each strategy.
The visualization and some statistics where inspired by the existing implementations of the "Seasonality" script, and the performance matrix implementations of @QuantNomad and @ZenAndTheArtOfTrading scripts.
While this library is meant to be used by my strategy framework "Template Trailing Strategy (Backtester)" script, I wrapped it in a library hoping this can be usefull for other community strategy scripts that will be released in the future.
🤔 How to Guide
To use the functionality this library provides in your script you have to import it first!
Copy the import statement of the latest release by pressing the copy button below and then paste it into your script. Give a short name to this library so you can refer to it later on. The import statement should look like this:
import jason5480/analytics_tables/1 as ant
There are three types of tables provided by this library in the initial release. The stats table the metrics table and the seasonality table.
Each one shows different kinds of performance statistics.
The table UDT shall be initialized once using the `init()` method.
They can be updated using the `update()` method where the updated data UDT object shall be passed.
The data UDT can also initialized and get updated on demend depending on the use case
A code example for the StatsTable is the following:
var ant.StatsData statsData = ant.StatsData.new()
statsData.update(SideStats.new(), SideStats.new(), 0)
if (barstate.islastconfirmedhistory or (barstate.isrealtime and barstate.isconfirmed))
var statsTable = ant.StatsTable.new().init(ant.getTablePos('TOP', 'RIGHT'))
statsTable.update(statsData)
A code example for the MetricsTable is the following:
var ant.StatsData statsData = ant.StatsData.new()
statsData.update(ant.SideStats.new(), ant.SideStats.new(), 0)
if (barstate.islastconfirmedhistory or (barstate.isrealtime and barstate.isconfirmed))
var metricsTable = ant.MetricsTable.new().init(ant.getTablePos('BOTTOM', 'RIGHT'))
metricsTable.update(statsData, 10)
A code example for the SeasonalityTable is the following:
var ant.SeasonalData seasonalData = ant.SeasonalData.new().init(Seasonality.monthOfYear)
seasonalData.update()
if (barstate.islastconfirmedhistory or (barstate.isrealtime and barstate.isconfirmed))
var seasonalTable = ant.SeasonalTable.new().init(seasonalData, ant.getTablePos('BOTTOM', 'LEFT'))
seasonalTable.update(seasonalData)
🏋️♂️ Please refer to the "EXAMPLE" regions of the script for more advanced and up to date code examples!
Special thanks to @Mrcrbw for the proposal to develop this library and @DCNeu for the constructive feedback 🏆.
getTablePos(ypos, xpos)
Get table position compatible string
Parameters:
ypos (simple string) : The position on y axise
xpos (simple string) : The position on x axise
Returns: The position to be passed to the table
method init(this, pos, height, width, positiveTxtColor, negativeTxtColor, neutralTxtColor, positiveBgColor, negativeBgColor, neutralBgColor)
Initialize the stats table object with the given colors in the given position
Namespace types: StatsTable
Parameters:
this (StatsTable) : The stats table object
pos (simple string) : The table position string
height (simple float) : The height of the table as a percentage of the charts height. By default, 0 auto-adjusts the height based on the text inside the cells
width (simple float) : The width of the table as a percentage of the charts height. By default, 0 auto-adjusts the width based on the text inside the cells
positiveTxtColor (simple color) : The text color when positive
negativeTxtColor (simple color) : The text color when negative
neutralTxtColor (simple color) : The text color when neutral
positiveBgColor (simple color) : The background color with transparency when positive
negativeBgColor (simple color) : The background color with transparency when negative
neutralBgColor (simple color) : The background color with transparency when neutral
method init(this, pos, height, width, neutralBgColor)
Initialize the metrics table object with the given colors in the given position
Namespace types: MetricsTable
Parameters:
this (MetricsTable) : The metrics table object
pos (simple string) : The table position string
height (simple float) : The height of the table as a percentage of the charts height. By default, 0 auto-adjusts the height based on the text inside the cells
width (simple float) : The width of the table as a percentage of the charts width. By default, 0 auto-adjusts the width based on the text inside the cells
neutralBgColor (simple color) : The background color with transparency when neutral
method init(this, seas)
Initialize the seasonal data
Namespace types: SeasonalData
Parameters:
this (SeasonalData) : The seasonal data object
seas (simple Seasonality) : The seasonality of the matrix data
method init(this, data, pos, maxNumOfYears, height, width, extended, neutralTxtColor, neutralBgColor)
Initialize the seasonal table object with the given colors in the given position
Namespace types: SeasonalTable
Parameters:
this (SeasonalTable) : The seasonal table object
data (SeasonalData) : The seasonality data of the table
pos (simple string) : The table position string
maxNumOfYears (simple int) : The maximum number of years that fit into the table
height (simple float) : The height of the table as a percentage of the charts height. By default, 0 auto-adjusts the height based on the text inside the cells
width (simple float) : The width of the table as a percentage of the charts width. By default, 0 auto-adjusts the width based on the text inside the cells
extended (simple bool) : The seasonal table with extended columns for performance
neutralTxtColor (simple color) : The text color when neutral
neutralBgColor (simple color) : The background color with transparency when neutral
method update(this, wins, losses, numOfInconclusiveExits)
Update the strategy info data of the strategy
Namespace types: StatsData
Parameters:
this (StatsData) : The strategy statistics object
wins (SideStats)
losses (SideStats)
numOfInconclusiveExits (int) : The number of inconclusive trades
method update(this, stats, positiveTxtColor, negativeTxtColor, negativeBgColor, neutralBgColor)
Update the stats table object with the given data
Namespace types: StatsTable
Parameters:
this (StatsTable) : The stats table object
stats (StatsData) : The stats data to update the table
positiveTxtColor (simple color) : The text color when positive
negativeTxtColor (simple color) : The text color when negative
negativeBgColor (simple color) : The background color with transparency when negative
neutralBgColor (simple color) : The background color with transparency when neutral
method update(this, stats, buyAndHoldPerc, positiveTxtColor, negativeTxtColor, positiveBgColor, negativeBgColor)
Update the metrics table object with the given data
Namespace types: MetricsTable
Parameters:
this (MetricsTable) : The metrics table object
stats (StatsData) : The stats data to update the table
buyAndHoldPerc (float) : The buy and hold percetage
positiveTxtColor (simple color) : The text color when positive
negativeTxtColor (simple color) : The text color when negative
positiveBgColor (simple color) : The background color with transparency when positive
negativeBgColor (simple color) : The background color with transparency when negative
method update(this)
Update the seasonal data based on the season and eon timeframe
Namespace types: SeasonalData
Parameters:
this (SeasonalData) : The seasonal data object
method update(this, data, positiveTxtColor, negativeTxtColor, neutralTxtColor, positiveBgColor, negativeBgColor, neutralBgColor, timeBgColor)
Update the seasonal table object with the given data
Namespace types: SeasonalTable
Parameters:
this (SeasonalTable) : The seasonal table object
data (SeasonalData) : The seasonal cell data to update the table
positiveTxtColor (simple color) : The text color when positive
negativeTxtColor (simple color) : The text color when negative
neutralTxtColor (simple color) : The text color when neutral
positiveBgColor (simple color) : The background color with transparency when positive
negativeBgColor (simple color) : The background color with transparency when negative
neutralBgColor (simple color) : The background color with transparency when neutral
timeBgColor (simple color) : The background color of the time gradient
SideStats
Object that represents the strategy statistics data of one side win or lose
Fields:
numOf (series int)
sumFreeProfit (series float)
freeProfitStDev (series float)
sumProfit (series float)
profitStDev (series float)
sumGain (series float)
gainStDev (series float)
avgQuantityPerc (series float)
avgCapitalRiskPerc (series float)
avgTPExecutedCount (series float)
avgRiskRewardRatio (series float)
maxStreak (series int)
StatsTable
Object that represents the stats table
Fields:
table (series table) : The actual table
rows (series int) : The number of rows of the table
columns (series int) : The number of columns of the table
StatsData
Object that represents the statistics data of the strategy
Fields:
wins (SideStats)
losses (SideStats)
numOfInconclusiveExits (series int)
avgFreeProfitStr (series string)
freeProfitStDevStr (series string)
lossFreeProfitStDevStr (series string)
avgProfitStr (series string)
profitStDevStr (series string)
lossProfitStDevStr (series string)
avgQuantityStr (series string)
MetricsTable
Object that represents the metrics table
Fields:
table (series table) : The actual table
rows (series int) : The number of rows of the table
columns (series int) : The number of columns of the table
SeasonalData
Object that represents the seasonal table dynamic data
Fields:
seasonality (series Seasonality)
eonToMatrixRow (map)
numOfEons (series int)
mostRecentMatrixRow (series int)
balances (matrix)
returnPercs (matrix)
maxDDs (matrix)
eonReturnPercs (array)
eonCAGRs (array)
eonMaxDDs (array)
SeasonalTable
Object that represents the seasonal table
Fields:
table (series table) : The actual table
headRows (series int) : The number of head rows of the table
headColumns (series int) : The number of head columns of the table
eonRows (series int) : The number of eon rows of the table
seasonColumns (series int) : The number of season columns of the table
statsRows (series int)
statsColumns (series int) : The number of stats columns of the table
rows (series int) : The number of rows of the table
columns (series int) : The number of columns of the table
extended (series bool) : Whether the table has additional performance statistics
Quantum Rotational Field MappingQuantum Rotational Field Mapping (QRFM):
Phase Coherence Detection Through Complex-Plane Oscillator Analysis
Quantum Rotational Field Mapping applies complex-plane mathematics and phase-space analysis to oscillator ensembles, identifying high-probability trend ignition points by measuring when multiple independent oscillators achieve phase coherence. Unlike traditional multi-oscillator approaches that simply stack indicators or use boolean AND/OR logic, this system converts each oscillator into a rotating phasor (vector) in the complex plane and calculates the Coherence Index (CI) —a mathematical measure of how tightly aligned the ensemble has become—then generates signals only when alignment, phase direction, and pairwise entanglement all converge.
The indicator combines three mathematical frameworks: phasor representation using analytic signal theory to extract phase and amplitude from each oscillator, coherence measurement using vector summation in the complex plane to quantify group alignment, and entanglement analysis that calculates pairwise phase agreement across all oscillator combinations. This creates a multi-dimensional confirmation system that distinguishes between random oscillator noise and genuine regime transitions.
What Makes This Original
Complex-Plane Phasor Framework
This indicator implements classical signal processing mathematics adapted for market oscillators. Each oscillator—whether RSI, MACD, Stochastic, CCI, Williams %R, MFI, ROC, or TSI—is first normalized to a common scale, then converted into a complex-plane representation using an in-phase (I) and quadrature (Q) component. The in-phase component is the oscillator value itself, while the quadrature component is calculated as the first difference (derivative proxy), creating a velocity-aware representation.
From these components, the system extracts:
Phase (φ) : Calculated as φ = atan2(Q, I), representing the oscillator's position in its cycle (mapped to -180° to +180°)
Amplitude (A) : Calculated as A = √(I² + Q²), representing the oscillator's strength or conviction
This mathematical approach is fundamentally different from simply reading oscillator values. A phasor captures both where an oscillator is in its cycle (phase angle) and how strongly it's expressing that position (amplitude). Two oscillators can have the same value but be in opposite phases of their cycles—traditional analysis would see them as identical, while QRFM sees them as 180° out of phase (contradictory).
Coherence Index Calculation
The core innovation is the Coherence Index (CI) , borrowed from physics and signal processing. When you have N oscillators, each with phase φₙ, you can represent each as a unit vector in the complex plane: e^(iφₙ) = cos(φₙ) + i·sin(φₙ).
The CI measures what happens when you sum all these vectors:
Resultant Vector : R = Σ e^(iφₙ) = Σ cos(φₙ) + i·Σ sin(φₙ)
Coherence Index : CI = |R| / N
Where |R| is the magnitude of the resultant vector and N is the number of active oscillators.
The CI ranges from 0 to 1:
CI = 1.0 : Perfect coherence—all oscillators have identical phase angles, vectors point in the same direction, creating maximum constructive interference
CI = 0.0 : Complete decoherence—oscillators are randomly distributed around the circle, vectors cancel out through destructive interference
0 < CI < 1 : Partial alignment—some clustering with some scatter
This is not a simple average or correlation. The CI captures phase synchronization across the entire ensemble simultaneously. When oscillators phase-lock (align their cycles), the CI spikes regardless of their individual values. This makes it sensitive to regime transitions that traditional indicators miss.
Dominant Phase and Direction Detection
Beyond measuring alignment strength, the system calculates the dominant phase of the ensemble—the direction the resultant vector points:
Dominant Phase : φ_dom = atan2(Σ sin(φₙ), Σ cos(φₙ))
This gives the "average direction" of all oscillator phases, mapped to -180° to +180°:
+90° to -90° (right half-plane): Bullish phase dominance
+90° to +180° or -90° to -180° (left half-plane): Bearish phase dominance
The combination of CI magnitude (coherence strength) and dominant phase angle (directional bias) creates a two-dimensional signal space. High CI alone is insufficient—you need high CI plus dominant phase pointing in a tradeable direction. This dual requirement is what separates QRFM from simple oscillator averaging.
Entanglement Matrix and Pairwise Coherence
While the CI measures global alignment, the entanglement matrix measures local pairwise relationships. For every pair of oscillators (i, j), the system calculates:
E(i,j) = |cos(φᵢ - φⱼ)|
This represents the phase agreement between oscillators i and j:
E = 1.0 : Oscillators are in-phase (0° or 360° apart)
E = 0.0 : Oscillators are in quadrature (90° apart, orthogonal)
E between 0 and 1 : Varying degrees of alignment
The system counts how many oscillator pairs exceed a user-defined entanglement threshold (e.g., 0.7). This entangled pairs count serves as a confirmation filter: signals require not just high global CI, but also a minimum number of strong pairwise agreements. This prevents false ignitions where CI is high but driven by only two oscillators while the rest remain scattered.
The entanglement matrix creates an N×N symmetric matrix that can be visualized as a web—when many cells are bright (high E values), the ensemble is highly interconnected. When cells are dark, oscillators are moving independently.
Phase-Lock Tolerance Mechanism
A complementary confirmation layer is the phase-lock detector . This calculates the maximum phase spread across all oscillators:
For all pairs (i,j), compute angular distance: Δφ = |φᵢ - φⱼ|, wrapping at 180°
Max Spread = maximum Δφ across all pairs
If max spread < user threshold (e.g., 35°), the ensemble is considered phase-locked —all oscillators are within a narrow angular band.
This differs from entanglement: entanglement measures pairwise cosine similarity (magnitude of alignment), while phase-lock measures maximum angular deviation (tightness of clustering). Both must be satisfied for the highest-conviction signals.
Multi-Layer Visual Architecture
QRFM includes six visual components that represent the same underlying mathematics from different perspectives:
Circular Orbit Plot : A polar coordinate grid showing each oscillator as a vector from origin to perimeter. Angle = phase, radius = amplitude. This is a real-time snapshot of the complex plane. When vectors converge (point in similar directions), coherence is high. When scattered randomly, coherence is low. Users can see phase alignment forming before CI numerically confirms it.
Phase-Time Heat Map : A 2D matrix with rows = oscillators and columns = time bins. Each cell is colored by the oscillator's phase at that time (using a gradient where color hue maps to angle). Horizontal color bands indicate sustained phase alignment over time. Vertical color bands show moments when all oscillators shared the same phase (ignition points). This provides historical pattern recognition.
Entanglement Web Matrix : An N×N grid showing E(i,j) for all pairs. Cells are colored by entanglement strength—bright yellow/gold for high E, dark gray for low E. This reveals which oscillators are driving coherence and which are lagging. For example, if RSI and MACD show high E but Stochastic shows low E with everything, Stochastic is the outlier.
Quantum Field Cloud : A background color overlay on the price chart. Color (green = bullish, red = bearish) is determined by dominant phase. Opacity is determined by CI—high CI creates dense, opaque cloud; low CI creates faint, nearly invisible cloud. This gives an atmospheric "feel" for regime strength without looking at numbers.
Phase Spiral : A smoothed plot of dominant phase over recent history, displayed as a curve that wraps around price. When the spiral is tight and rotating steadily, the ensemble is in coherent rotation (trending). When the spiral is loose or erratic, coherence is breaking down.
Dashboard : A table showing real-time metrics: CI (as percentage), dominant phase (in degrees with directional arrow), field strength (CI × average amplitude), entangled pairs count, phase-lock status (locked/unlocked), quantum state classification ("Ignition", "Coherent", "Collapse", "Chaos"), and collapse risk (recent CI change normalized to 0-100%).
Each component is independently toggleable, allowing users to customize their workspace. The orbit plot is the most essential—it provides intuitive, visual feedback on phase alignment that no numerical dashboard can match.
Core Components and How They Work Together
1. Oscillator Normalization Engine
The foundation is creating a common measurement scale. QRFM supports eight oscillators:
RSI : Normalized from to using overbought/oversold levels (70, 30) as anchors
MACD Histogram : Normalized by dividing by rolling standard deviation, then clamped to
Stochastic %K : Normalized from using (80, 20) anchors
CCI : Divided by 200 (typical extreme level), clamped to
Williams %R : Normalized from using (-20, -80) anchors
MFI : Normalized from using (80, 20) anchors
ROC : Divided by 10, clamped to
TSI : Divided by 50, clamped to
Each oscillator can be individually enabled/disabled. Only active oscillators contribute to phase calculations. The normalization removes scale differences—a reading of +0.8 means "strongly bullish" regardless of whether it came from RSI or TSI.
2. Analytic Signal Construction
For each active oscillator at each bar, the system constructs the analytic signal:
In-Phase (I) : The normalized oscillator value itself
Quadrature (Q) : The bar-to-bar change in the normalized value (first derivative approximation)
This creates a 2D representation: (I, Q). The phase is extracted as:
φ = atan2(Q, I) × (180 / π)
This maps the oscillator to a point on the unit circle. An oscillator at the same value but rising (positive Q) will have a different phase than one that is falling (negative Q). This velocity-awareness is critical—it distinguishes between "at resistance and stalling" versus "at resistance and breaking through."
The amplitude is extracted as:
A = √(I² + Q²)
This represents the distance from origin in the (I, Q) plane. High amplitude means the oscillator is far from neutral (strong conviction). Low amplitude means it's near zero (weak/transitional state).
3. Coherence Calculation Pipeline
For each bar (or every Nth bar if phase sample rate > 1 for performance):
Step 1 : Extract phase φₙ for each of the N active oscillators
Step 2 : Compute complex exponentials: Zₙ = e^(i·φₙ·π/180) = cos(φₙ·π/180) + i·sin(φₙ·π/180)
Step 3 : Sum the complex exponentials: R = Σ Zₙ = (Σ cos φₙ) + i·(Σ sin φₙ)
Step 4 : Calculate magnitude: |R| = √
Step 5 : Normalize by count: CI_raw = |R| / N
Step 6 : Smooth the CI: CI = SMA(CI_raw, smoothing_window)
The smoothing step (default 2 bars) removes single-bar noise spikes while preserving structural coherence changes. Users can adjust this to control reactivity versus stability.
The dominant phase is calculated as:
φ_dom = atan2(Σ sin φₙ, Σ cos φₙ) × (180 / π)
This is the angle of the resultant vector R in the complex plane.
4. Entanglement Matrix Construction
For all unique pairs of oscillators (i, j) where i < j:
Step 1 : Get phases φᵢ and φⱼ
Step 2 : Compute phase difference: Δφ = φᵢ - φⱼ (in radians)
Step 3 : Calculate entanglement: E(i,j) = |cos(Δφ)|
Step 4 : Store in symmetric matrix: matrix = matrix = E(i,j)
The matrix is then scanned: count how many E(i,j) values exceed the user-defined threshold (default 0.7). This count is the entangled pairs metric.
For visualization, the matrix is rendered as an N×N table where cell brightness maps to E(i,j) intensity.
5. Phase-Lock Detection
Step 1 : For all unique pairs (i, j), compute angular distance: Δφ = |φᵢ - φⱼ|
Step 2 : Wrap angles: if Δφ > 180°, set Δφ = 360° - Δφ
Step 3 : Find maximum: max_spread = max(Δφ) across all pairs
Step 4 : Compare to tolerance: phase_locked = (max_spread < tolerance)
If phase_locked is true, all oscillators are within the specified angular cone (e.g., 35°). This is a boolean confirmation filter.
6. Signal Generation Logic
Signals are generated through multi-layer confirmation:
Long Ignition Signal :
CI crosses above ignition threshold (e.g., 0.80)
AND dominant phase is in bullish range (-90° < φ_dom < +90°)
AND phase_locked = true
AND entangled_pairs >= minimum threshold (e.g., 4)
Short Ignition Signal :
CI crosses above ignition threshold
AND dominant phase is in bearish range (φ_dom < -90° OR φ_dom > +90°)
AND phase_locked = true
AND entangled_pairs >= minimum threshold
Collapse Signal :
CI at bar minus CI at current bar > collapse threshold (e.g., 0.55)
AND CI at bar was above 0.6 (must collapse from coherent state, not from already-low state)
These are strict conditions. A high CI alone does not generate a signal—dominant phase must align with direction, oscillators must be phase-locked, and sufficient pairwise entanglement must exist. This multi-factor gating dramatically reduces false signals compared to single-condition triggers.
Calculation Methodology
Phase 1: Oscillator Computation and Normalization
On each bar, the system calculates the raw values for all enabled oscillators using standard Pine Script functions:
RSI: ta.rsi(close, length)
MACD: ta.macd() returning histogram component
Stochastic: ta.stoch() smoothed with ta.sma()
CCI: ta.cci(close, length)
Williams %R: ta.wpr(length)
MFI: ta.mfi(hlc3, length)
ROC: ta.roc(close, length)
TSI: ta.tsi(close, short, long)
Each raw value is then passed through a normalization function:
normalize(value, overbought_level, oversold_level) = 2 × (value - oversold) / (overbought - oversold) - 1
This maps the oscillator's typical range to , where -1 represents extreme bearish, 0 represents neutral, and +1 represents extreme bullish.
For oscillators without fixed ranges (MACD, ROC, TSI), statistical normalization is used: divide by a rolling standard deviation or fixed divisor, then clamp to .
Phase 2: Phasor Extraction
For each normalized oscillator value val:
I = val (in-phase component)
Q = val - val (quadrature component, first difference)
Phase calculation:
phi_rad = atan2(Q, I)
phi_deg = phi_rad × (180 / π)
Amplitude calculation:
A = √(I² + Q²)
These values are stored in arrays: osc_phases and osc_amps for each oscillator n.
Phase 3: Complex Summation and Coherence
Initialize accumulators:
sum_cos = 0
sum_sin = 0
For each oscillator n = 0 to N-1:
phi_rad = osc_phases × (π / 180)
sum_cos += cos(phi_rad)
sum_sin += sin(phi_rad)
Resultant magnitude:
resultant_mag = √(sum_cos² + sum_sin²)
Coherence Index (raw):
CI_raw = resultant_mag / N
Smoothed CI:
CI = SMA(CI_raw, smoothing_window)
Dominant phase:
phi_dom_rad = atan2(sum_sin, sum_cos)
phi_dom_deg = phi_dom_rad × (180 / π)
Phase 4: Entanglement Matrix Population
For i = 0 to N-2:
For j = i+1 to N-1:
phi_i = osc_phases × (π / 180)
phi_j = osc_phases × (π / 180)
delta_phi = phi_i - phi_j
E = |cos(delta_phi)|
matrix_index_ij = i × N + j
matrix_index_ji = j × N + i
entangle_matrix = E
entangle_matrix = E
if E >= threshold:
entangled_pairs += 1
The matrix uses flat array storage with index mapping: index(row, col) = row × N + col.
Phase 5: Phase-Lock Check
max_spread = 0
For i = 0 to N-2:
For j = i+1 to N-1:
delta = |osc_phases - osc_phases |
if delta > 180:
delta = 360 - delta
max_spread = max(max_spread, delta)
phase_locked = (max_spread < tolerance)
Phase 6: Signal Evaluation
Ignition Long :
ignition_long = (CI crosses above threshold) AND
(phi_dom > -90 AND phi_dom < 90) AND
phase_locked AND
(entangled_pairs >= minimum)
Ignition Short :
ignition_short = (CI crosses above threshold) AND
(phi_dom < -90 OR phi_dom > 90) AND
phase_locked AND
(entangled_pairs >= minimum)
Collapse :
CI_prev = CI
collapse = (CI_prev - CI > collapse_threshold) AND (CI_prev > 0.6)
All signals are evaluated on bar close. The crossover and crossunder functions ensure signals fire only once when conditions transition from false to true.
Phase 7: Field Strength and Visualization Metrics
Average Amplitude :
avg_amp = (Σ osc_amps ) / N
Field Strength :
field_strength = CI × avg_amp
Collapse Risk (for dashboard):
collapse_risk = (CI - CI) / max(CI , 0.1)
collapse_risk_pct = clamp(collapse_risk × 100, 0, 100)
Quantum State Classification :
if (CI > threshold AND phase_locked):
state = "Ignition"
else if (CI > 0.6):
state = "Coherent"
else if (collapse):
state = "Collapse"
else:
state = "Chaos"
Phase 8: Visual Rendering
Orbit Plot : For each oscillator, convert polar (phase, amplitude) to Cartesian (x, y) for grid placement:
radius = amplitude × grid_center × 0.8
x = radius × cos(phase × π/180)
y = radius × sin(phase × π/180)
col = center + x (mapped to grid coordinates)
row = center - y
Heat Map : For each oscillator row and time column, retrieve historical phase value at lookback = (columns - col) × sample_rate, then map phase to color using a hue gradient.
Entanglement Web : Render matrix as table cell with background color opacity = E(i,j).
Field Cloud : Background color = (phi_dom > -90 AND phi_dom < 90) ? green : red, with opacity = mix(min_opacity, max_opacity, CI).
All visual components render only on the last bar (barstate.islast) to minimize computational overhead.
How to Use This Indicator
Step 1 : Apply QRFM to your chart. It works on all timeframes and asset classes, though 15-minute to 4-hour timeframes provide the best balance of responsiveness and noise reduction.
Step 2 : Enable the dashboard (default: top right) and the circular orbit plot (default: middle left). These are your primary visual feedback tools.
Step 3 : Optionally enable the heat map, entanglement web, and field cloud based on your preference. New users may find all visuals overwhelming; start with dashboard + orbit plot.
Step 4 : Observe for 50-100 bars to let the indicator establish baseline coherence patterns. Markets have different "normal" CI ranges—some instruments naturally run higher or lower coherence.
Understanding the Circular Orbit Plot
The orbit plot is a polar grid showing oscillator vectors in real-time:
Center point : Neutral (zero phase and amplitude)
Each vector : A line from center to a point on the grid
Vector angle : The oscillator's phase (0° = right/east, 90° = up/north, 180° = left/west, -90° = down/south)
Vector length : The oscillator's amplitude (short = weak signal, long = strong signal)
Vector label : First letter of oscillator name (R = RSI, M = MACD, etc.)
What to watch :
Convergence : When all vectors cluster in one quadrant or sector, CI is rising and coherence is forming. This is your pre-signal warning.
Scatter : When vectors point in random directions (360° spread), CI is low and the market is in a non-trending or transitional regime.
Rotation : When the cluster rotates smoothly around the circle, the ensemble is in coherent oscillation—typically seen during steady trends.
Sudden flips : When the cluster rapidly jumps from one side to the opposite (e.g., +90° to -90°), a phase reversal has occurred—often coinciding with trend reversals.
Example: If you see RSI, MACD, and Stochastic all pointing toward 45° (northeast) with long vectors, while CCI, TSI, and ROC point toward 40-50° as well, coherence is high and dominant phase is bullish. Expect an ignition signal if CI crosses threshold.
Reading Dashboard Metrics
The dashboard provides numerical confirmation of what the orbit plot shows visually:
CI : Displays as 0-100%. Above 70% = high coherence (strong regime), 40-70% = moderate, below 40% = low (poor conditions for trend entries).
Dom Phase : Angle in degrees with directional arrow. ⬆ = bullish bias, ⬇ = bearish bias, ⬌ = neutral.
Field Strength : CI weighted by amplitude. High values (> 0.6) indicate not just alignment but strong alignment.
Entangled Pairs : Count of oscillator pairs with E > threshold. Higher = more confirmation. If minimum is set to 4, you need at least 4 pairs entangled for signals.
Phase Lock : 🔒 YES (all oscillators within tolerance) or 🔓 NO (spread too wide).
State : Real-time classification:
🚀 IGNITION: CI just crossed threshold with phase-lock
⚡ COHERENT: CI is high and stable
💥 COLLAPSE: CI has dropped sharply
🌀 CHAOS: Low CI, scattered phases
Collapse Risk : 0-100% scale based on recent CI change. Above 50% warns of imminent breakdown.
Interpreting Signals
Long Ignition (Blue Triangle Below Price) :
Occurs when CI crosses above threshold (e.g., 0.80)
Dominant phase is in bullish range (-90° to +90°)
All oscillators are phase-locked (within tolerance)
Minimum entangled pairs requirement met
Interpretation : The oscillator ensemble has transitioned from disorder to coherent bullish alignment. This is a high-probability long entry point. The multi-layer confirmation (CI + phase direction + lock + entanglement) ensures this is not a single-oscillator whipsaw.
Short Ignition (Red Triangle Above Price) :
Same conditions as long, but dominant phase is in bearish range (< -90° or > +90°)
Interpretation : Coherent bearish alignment has formed. High-probability short entry.
Collapse (Circles Above and Below Price) :
CI has dropped by more than the collapse threshold (e.g., 0.55) over a 5-bar window
CI was previously above 0.6 (collapsing from coherent state)
Interpretation : Phase coherence has broken down. If you are in a position, this is an exit warning. If looking to enter, stand aside—regime is transitioning.
Phase-Time Heat Map Patterns
Enable the heat map and position it at bottom right. The rows represent individual oscillators, columns represent time bins (most recent on left).
Pattern: Horizontal Color Bands
If a row (e.g., RSI) shows consistent color across columns (say, green for several bins), that oscillator has maintained stable phase over time. If all rows show horizontal bands of similar color, the entire ensemble has been phase-locked for an extended period—this is a strong trending regime.
Pattern: Vertical Color Bands
If a column (single time bin) shows all cells with the same or very similar color, that moment in time had high coherence. These vertical bands often align with ignition signals or major price pivots.
Pattern: Rainbow Chaos
If cells are random colors (red, green, yellow mixed with no pattern), coherence is low. The ensemble is scattered. Avoid trading during these periods unless you have external confirmation.
Pattern: Color Transition
If you see a row transition from red to green (or vice versa) sharply, that oscillator has phase-flipped. If multiple rows do this simultaneously, a regime change is underway.
Entanglement Web Analysis
Enable the web matrix (default: opposite corner from heat map). It shows an N×N grid where N = number of active oscillators.
Bright Yellow/Gold Cells : High pairwise entanglement. For example, if the RSI-MACD cell is bright gold, those two oscillators are moving in phase. If the RSI-Stochastic cell is bright, they are entangled as well.
Dark Gray Cells : Low entanglement. Oscillators are decorrelated or in quadrature.
Diagonal : Always marked with "—" because an oscillator is always perfectly entangled with itself.
How to use :
Scan for clustering: If most cells are bright, coherence is high across the board. If only a few cells are bright, coherence is driven by a subset (e.g., RSI and MACD are aligned, but nothing else is—weak signal).
Identify laggards: If one row/column is entirely dark, that oscillator is the outlier. You may choose to disable it or monitor for when it joins the group (late confirmation).
Watch for web formation: During low-coherence periods, the matrix is mostly dark. As coherence builds, cells begin lighting up. A sudden "web" of connections forming visually precedes ignition signals.
Trading Workflow
Step 1: Monitor Coherence Level
Check the dashboard CI metric or observe the orbit plot. If CI is below 40% and vectors are scattered, conditions are poor for trend entries. Wait.
Step 2: Detect Coherence Building
When CI begins rising (say, from 30% to 50-60%) and you notice vectors on the orbit plot starting to cluster, coherence is forming. This is your alert phase—do not enter yet, but prepare.
Step 3: Confirm Phase Direction
Check the dominant phase angle and the orbit plot quadrant where clustering is occurring:
Clustering in right half (0° to ±90°): Bullish bias forming
Clustering in left half (±90° to 180°): Bearish bias forming
Verify the dashboard shows the corresponding directional arrow (⬆ or ⬇).
Step 4: Wait for Signal Confirmation
Do not enter based on rising CI alone. Wait for the full ignition signal:
CI crosses above threshold
Phase-lock indicator shows 🔒 YES
Entangled pairs count >= minimum
Directional triangle appears on chart
This ensures all layers have aligned.
Step 5: Execute Entry
Long : Blue triangle below price appears → enter long
Short : Red triangle above price appears → enter short
Step 6: Position Management
Initial Stop : Place stop loss based on your risk management rules (e.g., recent swing low/high, ATR-based buffer).
Monitoring :
Watch the field cloud density. If it remains opaque and colored in your direction, the regime is intact.
Check dashboard collapse risk. If it rises above 50%, prepare for exit.
Monitor the orbit plot. If vectors begin scattering or the cluster flips to the opposite side, coherence is breaking.
Exit Triggers :
Collapse signal fires (circles appear)
Dominant phase flips to opposite half-plane
CI drops below 40% (coherence lost)
Price hits your profit target or trailing stop
Step 7: Post-Exit Analysis
After exiting, observe whether a new ignition forms in the opposite direction (reversal) or if CI remains low (transition to range). Use this to decide whether to re-enter, reverse, or stand aside.
Best Practices
Use Price Structure as Context
QRFM identifies when coherence forms but does not specify where price will go. Combine ignition signals with support/resistance levels, trendlines, or chart patterns. For example:
Long ignition near a major support level after a pullback: high-probability bounce
Long ignition in the middle of a range with no structure: lower probability
Multi-Timeframe Confirmation
Open QRFM on two timeframes simultaneously:
Higher timeframe (e.g., 4-hour): Use CI level to determine regime bias. If 4H CI is above 60% and dominant phase is bullish, the market is in a bullish regime.
Lower timeframe (e.g., 15-minute): Execute entries on ignition signals that align with the higher timeframe bias.
This prevents counter-trend trades and increases win rate.
Distinguish Between Regime Types
High CI, stable dominant phase (State: Coherent) : Trending market. Ignitions are continuation signals; collapses are profit-taking or reversal warnings.
Low CI, erratic dominant phase (State: Chaos) : Ranging or choppy market. Avoid ignition signals or reduce position size. Wait for coherence to establish.
Moderate CI with frequent collapses : Whipsaw environment. Use wider stops or stand aside.
Adjust Parameters to Instrument and Timeframe
Crypto/Forex (high volatility) : Lower ignition threshold (0.65-0.75), lower CI smoothing (2-3), shorter oscillator lengths (7-10).
Stocks/Indices (moderate volatility) : Standard settings (threshold 0.75-0.85, smoothing 5-7, oscillator lengths 14).
Lower timeframes (5-15 min) : Reduce phase sample rate to 1-2 for responsiveness.
Higher timeframes (daily+) : Increase CI smoothing and oscillator lengths for noise reduction.
Use Entanglement Count as Conviction Filter
The minimum entangled pairs setting controls signal strictness:
Low (1-2) : More signals, lower quality (acceptable if you have other confirmation)
Medium (3-5) : Balanced (recommended for most traders)
High (6+) : Very strict, fewer signals, highest quality
Adjust based on your trade frequency preference and risk tolerance.
Monitor Oscillator Contribution
Use the entanglement web to see which oscillators are driving coherence. If certain oscillators are consistently dark (low E with all others), they may be adding noise. Consider disabling them. For example:
On low-volume instruments, MFI may be unreliable → disable MFI
On strongly trending instruments, mean-reversion oscillators (Stochastic, RSI) may lag → reduce weight or disable
Respect the Collapse Signal
Collapse events are early warnings. Price may continue in the original direction for several bars after collapse fires, but the underlying regime has weakened. Best practice:
If in profit: Take partial or full profit on collapse
If at breakeven/small loss: Exit immediately
If collapse occurs shortly after entry: Likely a false ignition; exit to avoid drawdown
Collapses do not guarantee immediate reversals—they signal uncertainty .
Combine with Volume Analysis
If your instrument has reliable volume:
Ignitions with expanding volume: Higher conviction
Ignitions with declining volume: Weaker, possibly false
Collapses with volume spikes: Strong reversal signal
Collapses with low volume: May just be consolidation
Volume is not built into QRFM (except via MFI), so add it as external confirmation.
Observe the Phase Spiral
The spiral provides a quick visual cue for rotation consistency:
Tight, smooth spiral : Ensemble is rotating coherently (trending)
Loose, erratic spiral : Phase is jumping around (ranging or transitional)
If the spiral tightens, coherence is building. If it loosens, coherence is dissolving.
Do Not Overtrade Low-Coherence Periods
When CI is persistently below 40% and the state is "Chaos," the market is not in a regime where phase analysis is predictive. During these times:
Reduce position size
Widen stops
Wait for coherence to return
QRFM's strength is regime detection. If there is no regime, the tool correctly signals "stand aside."
Use Alerts Strategically
Set alerts for:
Long Ignition
Short Ignition
Collapse
Phase Lock (optional)
Configure alerts to "Once per bar close" to avoid intrabar repainting and noise. When an alert fires, manually verify:
Orbit plot shows clustering
Dashboard confirms all conditions
Price structure supports the trade
Do not blindly trade alerts—use them as prompts for analysis.
Ideal Market Conditions
Best Performance
Instruments :
Liquid, actively traded markets (major forex pairs, large-cap stocks, major indices, top-tier crypto)
Instruments with clear cyclical oscillator behavior (avoid extremely illiquid or manipulated markets)
Timeframes :
15-minute to 4-hour: Optimal balance of noise reduction and responsiveness
1-hour to daily: Slower, higher-conviction signals; good for swing trading
5-minute: Acceptable for scalping if parameters are tightened and you accept more noise
Market Regimes :
Trending markets with periodic retracements (where oscillators cycle through phases predictably)
Breakout environments (coherence forms before/during breakout; collapse occurs at exhaustion)
Rotational markets with clear swings (oscillators phase-lock at turning points)
Volatility :
Moderate to high volatility (oscillators have room to move through their ranges)
Stable volatility regimes (sudden VIX spikes or flash crashes may create false collapses)
Challenging Conditions
Instruments :
Very low liquidity markets (erratic price action creates unstable oscillator phases)
Heavily news-driven instruments (fundamentals may override technical coherence)
Highly correlated instruments (oscillators may all reflect the same underlying factor, reducing independence)
Market Regimes :
Deep, prolonged consolidation (oscillators remain near neutral, CI is chronically low, few signals fire)
Extreme chop with no directional bias (oscillators whipsaw, coherence never establishes)
Gap-driven markets (large overnight gaps create phase discontinuities)
Timeframes :
Sub-5-minute charts: Noise dominates; oscillators flip rapidly; coherence is fleeting and unreliable
Weekly/monthly: Oscillators move extremely slowly; signals are rare; better suited for long-term positioning than active trading
Special Cases :
During major economic releases or earnings: Oscillators may lag price or become decorrelated as fundamentals overwhelm technicals. Reduce position size or stand aside.
In extremely low-volatility environments (e.g., holiday periods): Oscillators compress to neutral, CI may be artificially high due to lack of movement, but signals lack follow-through.
Adaptive Behavior
QRFM is designed to self-adapt to poor conditions:
When coherence is genuinely absent, CI remains low and signals do not fire
When only a subset of oscillators aligns, entangled pairs count stays below threshold and signals are filtered out
When phase-lock cannot be achieved (oscillators too scattered), the lock filter prevents signals
This means the indicator will naturally produce fewer (or zero) signals during unfavorable conditions, rather than generating false signals. This is a feature —it keeps you out of low-probability trades.
Parameter Optimization by Trading Style
Scalping (5-15 Minute Charts)
Goal : Maximum responsiveness, accept higher noise
Oscillator Lengths :
RSI: 7-10
MACD: 8/17/6
Stochastic: 8-10, smooth 2-3
CCI: 14-16
Others: 8-12
Coherence Settings :
CI Smoothing Window: 2-3 bars (fast reaction)
Phase Sample Rate: 1 (every bar)
Ignition Threshold: 0.65-0.75 (lower for more signals)
Collapse Threshold: 0.40-0.50 (earlier exit warnings)
Confirmation :
Phase Lock Tolerance: 40-50° (looser, easier to achieve)
Min Entangled Pairs: 2-3 (fewer oscillators required)
Visuals :
Orbit Plot + Dashboard only (reduce screen clutter for fast decisions)
Disable heavy visuals (heat map, web) for performance
Alerts :
Enable all ignition and collapse alerts
Set to "Once per bar close"
Day Trading (15-Minute to 1-Hour Charts)
Goal : Balance between responsiveness and reliability
Oscillator Lengths :
RSI: 14 (standard)
MACD: 12/26/9 (standard)
Stochastic: 14, smooth 3
CCI: 20
Others: 10-14
Coherence Settings :
CI Smoothing Window: 3-5 bars (balanced)
Phase Sample Rate: 2-3
Ignition Threshold: 0.75-0.85 (moderate selectivity)
Collapse Threshold: 0.50-0.55 (balanced exit timing)
Confirmation :
Phase Lock Tolerance: 30-40° (moderate tightness)
Min Entangled Pairs: 4-5 (reasonable confirmation)
Visuals :
Orbit Plot + Dashboard + Heat Map or Web (choose one)
Field Cloud for regime backdrop
Alerts :
Ignition and collapse alerts
Optional phase-lock alert for advance warning
Swing Trading (4-Hour to Daily Charts)
Goal : High-conviction signals, minimal noise, fewer trades
Oscillator Lengths :
RSI: 14-21
MACD: 12/26/9 or 19/39/9 (longer variant)
Stochastic: 14-21, smooth 3-5
CCI: 20-30
Others: 14-20
Coherence Settings :
CI Smoothing Window: 5-10 bars (very smooth)
Phase Sample Rate: 3-5
Ignition Threshold: 0.80-0.90 (high bar for entry)
Collapse Threshold: 0.55-0.65 (only significant breakdowns)
Confirmation :
Phase Lock Tolerance: 20-30° (tight clustering required)
Min Entangled Pairs: 5-7 (strong confirmation)
Visuals :
All modules enabled (you have time to analyze)
Heat Map for multi-bar pattern recognition
Web for deep confirmation analysis
Alerts :
Ignition and collapse
Review manually before entering (no rush)
Position/Long-Term Trading (Daily to Weekly Charts)
Goal : Rare, very high-conviction regime shifts
Oscillator Lengths :
RSI: 21-30
MACD: 19/39/9 or 26/52/12
Stochastic: 21, smooth 5
CCI: 30-50
Others: 20-30
Coherence Settings :
CI Smoothing Window: 10-14 bars
Phase Sample Rate: 5 (every 5th bar to reduce computation)
Ignition Threshold: 0.85-0.95 (only extreme alignment)
Collapse Threshold: 0.60-0.70 (major regime breaks only)
Confirmation :
Phase Lock Tolerance: 15-25° (very tight)
Min Entangled Pairs: 6+ (broad consensus required)
Visuals :
Dashboard + Orbit Plot for quick checks
Heat Map to study historical coherence patterns
Web to verify deep entanglement
Alerts :
Ignition only (collapses are less critical on long timeframes)
Manual review with fundamental analysis overlay
Performance Optimization (Low-End Systems)
If you experience lag or slow rendering:
Reduce Visual Load :
Orbit Grid Size: 8-10 (instead of 12+)
Heat Map Time Bins: 5-8 (instead of 10+)
Disable Web Matrix entirely if not needed
Disable Field Cloud and Phase Spiral
Reduce Calculation Frequency :
Phase Sample Rate: 5-10 (calculate every 5-10 bars)
Max History Depth: 100-200 (instead of 500+)
Disable Unused Oscillators :
If you only want RSI, MACD, and Stochastic, disable the other five. Fewer oscillators = smaller matrices, faster loops.
Simplify Dashboard :
Choose "Small" dashboard size
Reduce number of metrics displayed
These settings will not significantly degrade signal quality (signals are based on bar-close calculations, which remain accurate), but will improve chart responsiveness.
Important Disclaimers
This indicator is a technical analysis tool designed to identify periods of phase coherence across an ensemble of oscillators. It is not a standalone trading system and does not guarantee profitable trades. The Coherence Index, dominant phase, and entanglement metrics are mathematical calculations applied to historical price data—they measure past oscillator behavior and do not predict future price movements with certainty.
No Predictive Guarantee : High coherence indicates that oscillators are currently aligned, which historically has coincided with trending or directional price movement. However, past alignment does not guarantee future trends. Markets can remain coherent while prices consolidate, or lose coherence suddenly due to news, liquidity changes, or other factors not captured by oscillator mathematics.
Signal Confirmation is Probabilistic : The multi-layer confirmation system (CI threshold + dominant phase + phase-lock + entanglement) is designed to filter out low-probability setups. This increases the proportion of valid signals relative to false signals, but does not eliminate false signals entirely. Users should combine QRFM with additional analysis—support and resistance levels, volume confirmation, multi-timeframe alignment, and fundamental context—before executing trades.
Collapse Signals are Warnings, Not Reversals : A coherence collapse indicates that the oscillator ensemble has lost alignment. This often precedes trend exhaustion or reversals, but can also occur during healthy pullbacks or consolidations. Price may continue in the original direction after a collapse. Use collapses as risk management cues (tighten stops, take partial profits) rather than automatic reversal entries.
Market Regime Dependency : QRFM performs best in markets where oscillators exhibit cyclical, mean-reverting behavior and where trends are punctuated by retracements. In markets dominated by fundamental shocks, gap openings, or extreme low-liquidity conditions, oscillator coherence may be less reliable. During such periods, reduce position size or stand aside.
Risk Management is Essential : All trading involves risk of loss. Use appropriate stop losses, position sizing, and risk-per-trade limits. The indicator does not specify stop loss or take profit levels—these must be determined by the user based on their risk tolerance and account size. Never risk more than you can afford to lose.
Parameter Sensitivity : The indicator's behavior changes with input parameters. Aggressive settings (low thresholds, loose tolerances) produce more signals with lower average quality. Conservative settings (high thresholds, tight tolerances) produce fewer signals with higher average quality. Users should backtest and forward-test parameter sets on their specific instruments and timeframes before committing real capital.
No Repainting by Design : All signal conditions are evaluated on bar close using bar-close values. However, the visual components (orbit plot, heat map, dashboard) update in real-time during bar formation for monitoring purposes. For trade execution, rely on the confirmed signals (triangles and circles) that appear only after the bar closes.
Computational Load : QRFM performs extensive calculations, including nested loops for entanglement matrices and real-time table rendering. On lower-powered devices or when running multiple indicators simultaneously, users may experience lag. Use the performance optimization settings (reduce visual complexity, increase phase sample rate, disable unused oscillators) to improve responsiveness.
This system is most effective when used as one component within a broader trading methodology that includes sound risk management, multi-timeframe analysis, market context awareness, and disciplined execution. It is a tool for regime detection and signal confirmation, not a substitute for comprehensive trade planning.
Technical Notes
Calculation Timing : All signal logic (ignition, collapse) is evaluated using bar-close values. The barstate.isconfirmed or implicit bar-close behavior ensures signals do not repaint. Visual components (tables, plots) render on every tick for real-time feedback but do not affect signal generation.
Phase Wrapping : Phase angles are calculated in the range -180° to +180° using atan2. Angular distance calculations account for wrapping (e.g., the distance between +170° and -170° is 20°, not 340°). This ensures phase-lock detection works correctly across the ±180° boundary.
Array Management : The indicator uses fixed-size arrays for oscillator phases, amplitudes, and the entanglement matrix. The maximum number of oscillators is 8. If fewer oscillators are enabled, array sizes shrink accordingly (only active oscillators are processed).
Matrix Indexing : The entanglement matrix is stored as a flat array with size N×N, where N is the number of active oscillators. Index mapping: index(row, col) = row × N + col. Symmetric pairs (i,j) and (j,i) are stored identically.
Normalization Stability : Oscillators are normalized to using fixed reference levels (e.g., RSI overbought/oversold at 70/30). For unbounded oscillators (MACD, ROC, TSI), statistical normalization (division by rolling standard deviation) is used, with clamping to prevent extreme outliers from distorting phase calculations.
Smoothing and Lag : The CI smoothing window (SMA) introduces lag proportional to the window size. This is intentional—it filters out single-bar noise spikes in coherence. Users requiring faster reaction can reduce the smoothing window to 1-2 bars, at the cost of increased sensitivity to noise.
Complex Number Representation : Pine Script does not have native complex number types. Complex arithmetic is implemented using separate real and imaginary accumulators (sum_cos, sum_sin) and manual calculation of magnitude (sqrt(real² + imag²)) and argument (atan2(imag, real)).
Lookback Limits : The indicator respects Pine Script's maximum lookback constraints. Historical phase and amplitude values are accessed using the operator, with lookback limited to the chart's available bar history (max_bars_back=5000 declared).
Visual Rendering Performance : Tables (orbit plot, heat map, web, dashboard) are conditionally deleted and recreated on each update using table.delete() and table.new(). This prevents memory leaks but incurs redraw overhead. Rendering is restricted to barstate.islast (last bar) to minimize computational load—historical bars do not render visuals.
Alert Condition Triggers : alertcondition() functions evaluate on bar close when their boolean conditions transition from false to true. Alerts do not fire repeatedly while a condition remains true (e.g., CI stays above threshold for 10 bars fires only once on the initial cross).
Color Gradient Functions : The phaseColor() function maps phase angles to RGB hues using sine waves offset by 120° (red, green, blue channels). This creates a continuous spectrum where -180° to +180° spans the full color wheel. The amplitudeColor() function maps amplitude to grayscale intensity. The coherenceColor() function uses cos(phase) to map contribution to CI (positive = green, negative = red).
No External Data Requests : QRFM operates entirely on the chart's symbol and timeframe. It does not use request.security() or access external data sources. All calculations are self-contained, avoiding lookahead bias from higher-timeframe requests.
Deterministic Behavior : Given identical input parameters and price data, QRFM produces identical outputs. There are no random elements, probabilistic sampling, or time-of-day dependencies.
— Dskyz, Engineering precision. Trading coherence.
DebugLibrary "Debug"
Some debugging functions.
label_on_each_bar(txt, y_position, label_size, label_color, txt_color)
Prints a label on every bar to show text. By default, only the last 50 labels will be shown on the chart. You can increase this amount up to a maximum of 500 by using the max_labels_count parameter in your script’s indicator() or strategy() declaration statement.
Parameters:
txt (string) : New label text.
y_position (float) : New price of the label position.
label_size (string) : Possible values: size.auto, size.tiny, size.small, size.normal, size.large, size.huge. Optional. Default value is `size.small`.
label_color (color) : New label border and arrow color. Optional. Default value is `color.blue`.
txt_color (color) : New text color. Optional. Default value is `color.white`.
Returns: void
label_on_last_bar(txt, y_position, label_size, label_color, txt_color, txt_align)
Prints one label at last bar to show text.
Parameters:
txt (string) : New label text.
y_position (float) : New price of the label position.
label_size (string) : Possible values: size.auto, size.tiny, size.small, size.normal, size.large, size.huge. Optional. Default value is `size.large`.
label_color (color) : New label border and arrow color. Optional. Default value is `color.blue`.
txt_color (color) : New text color. Optional. Default value is `color.white`.
txt_align (string) : Label text alignment. Optional. Possible values: text.align_left, text.align_center, text.align_right. Default value is `text.align_center`.
Returns: void
table_symbol_informations(table_position, table_color, text_color)
Prints a table to show all the Symbol information, including its function names.
Parameters:
table_position (string) : Position of the table. Optional. Possible values are: position.top_left, position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right. Default value is `position.middle_right`.
table_color (color) : The background color of the table. Optional. The default is `color.yellow`.
text_color (color) : The color of the text. Optional. The default is `color.black`.
Returns: void
table_array_float(array_float, table_columns, table_rows, table_position, table_color, txt_color, txt_size)
Prints a table to show float values of an array.
Parameters:
array_float (float ) : The array that will be showed.
table_columns (int)
table_rows (int) : The number of rows to show the values.
table_position (string) : Position of the table. Optional. Possible values are: position.top_left, position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right. Default value is `position.bottom_center`.
table_color (color) : The background color of the table. Optional. By default there is no color.
txt_color (color)
txt_size (string) : Possible values: size.auto, size.tiny, size.small, size.normal, size.large, size.huge. Optional. Default value is `size.normal`.
Returns: void
table_array_int(array_float, table_columns, table_rows, table_position, table_color, txt_color, txt_size)
Prints a table to show int values of an array.
Parameters:
array_float (int ) : The array that will be showed.
table_columns (int)
table_rows (int) : The number of rows to show the values.
table_position (string) : Position of the table. Optional. Possible values are: position.top_left, position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right. Default value is `position.bottom_center`.
table_color (color) : The background color of the table. Optional. By default there is no color.
txt_color (color)
txt_size (string) : Possible values: size.auto, size.tiny, size.small, size.normal, size.large, size.huge. Optional. Default value is `size.normal`.
Returns: void
lower_tfLibrary "lower_tf"
█ OVERVIEW
This library is an enhanced (opinionated) version of the library originally developed by PineCoders contained in lower_tf .
It is a Pine Script® programming tool for advanced lower-timeframe selection and intra-bar analysis.
█ CONCEPTS
Lower Timeframe Analysis
Lower timeframe analysis refers to the analysis of price action and market microstructure using data from timeframes shorter than the current chart period. This technique allows traders and analysts to gain deeper insights into market dynamics, volume distribution, and the price movements occurring within each bar on the chart. In Pine Script®, the request.security_lower_tf() function allows this analysis by accessing intrabar data.
The library provides a comprehensive set of functions for accurate mapping of lower timeframes, dynamic precision control, and optimized historical coverage using request.security_lower_tf().
█ IMPROVEMENTS
The original library implemented ten precision levels. This enhanced version extends that to twelve levels, adding two ultra-high-precision options:
Coverage-Based Precision (Original 5 levels):
1. "Covering most chart bars (least precise)"
2. "Covering some chart bars (less precise)"
3. "Covering fewer chart bars (more precise)"
4. "Covering few chart bars (very precise)"
5. "Covering the least chart bars (most precise)"
Intrabar-Count-Based Precision (Expanded from 5 to 7 levels):
6. "~12 intrabars per chart bar"
7. "~24 intrabars per chart bar"
8. "~50 intrabars per chart bar"
9. "~100 intrabars per chart bar"
10. "~250 intrabars per chart bar"
11. "~500 intrabars per chart bar" ← NEW
12. "~1000 intrabars per chart bar" ← NEW
The key enhancements in this version include:
1. Extended Precision Range: Adds two ultra-high-precision levels (~500 and ~1000 intrabars) for advanced microstructure analysis requiring maximum granularity.
2. Market-Agnostic Implementation: Eliminates the distinction between crypto/forex and traditional markets, removing the mktFactor variable in favor of a unified, predictable approach across all asset classes.
3. Explicit Precision Mapping: Completely refactors the timeframe selection logic using native Pine Script® timeframe properties ( timeframe.isseconds , timeframe.isminutes , timeframe.isdaily , timeframe.isweekly , timeframe.ismonthly ) and explicit multiplier-based lookup tables. The original library used minute-based calculations with market-dependent conditionals that produced inconsistent results. This version provides deterministic, predictable mappings for every chart timeframe, ensuring consistent precision behavior regardless of asset type or market hours.
An example of the differences can be seen side-by-side in the chart below, where the original library is on the left and the enhanced version is on the right:
█ USAGE EXAMPLE
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © andre_007
//@version=6
indicator("lower_tf Example")
import andre_007/lower_tf/1 as LTF
import PineCoders/Time/5 as PCtime
//#region ———————————————————— Example code
// ————— Constants
color WHITE = color.white
color GRAY = color.gray
string LTF1 = "Covering most chart bars (least precise)"
string LTF2 = "Covering some chart bars (less precise)"
string LTF3 = "Covering less chart bars (more precise)"
string LTF4 = "Covering few chart bars (very precise)"
string LTF5 = "Covering the least chart bars (most precise)"
string LTF6 = "~12 intrabars per chart bar"
string LTF7 = "~24 intrabars per chart bar"
string LTF8 = "~50 intrabars per chart bar"
string LTF9 = "~100 intrabars per chart bar"
string LTF10 = "~250 intrabars per chart bar"
string LTF11 = "~500 intrabars per chart bar"
string LTF12 = "~1000 intrabars per chart bar"
string TT_LTF = "This selection determines the approximate number of intrabars analyzed per chart bar. Higher numbers of
intrabars produce more granular data at the cost of less historical bar coverage, because the maximum number of
available intrabars is 200K.
\n\nThe first five options set the lower timeframe based on a specified relative level of chart bar coverage.
The last five options set the lower timeframe based on an approximate number of intrabars per chart bar."
string TAB_TXT = "Uses intrabars at the {0} timeframe.\nAvg intrabars per chart bar:
{1,number,#.#}\nChart bars covered: {2} of {3} ({4,number,#.##}%)"
string ERR_TXT = "No intrabar information exists at the {1}{0}{1} timeframe."
// ————— Inputs
string ltfModeInput = input.string(LTF3, "Intrabar precision", options = , tooltip = TT_LTF)
bool showInfoBoxInput = input.bool(true, "Show information box ")
string infoBoxSizeInput = input.string("normal", "Size ", inline = "01", options = )
string infoBoxYPosInput = input.string("bottom", "↕", inline = "01", options = )
string infoBoxXPosInput = input.string("right", "↔", inline = "01", options = )
color infoBoxColorInput = input.color(GRAY, "", inline = "01")
color infoBoxTxtColorInput = input.color(WHITE, "T", inline = "01")
// ————— Calculations
// @variable A "string" representing the lower timeframe for the data request.
// NOTE:
// This line is a good example where using `var` in the declaration can improve a script's performance.
// By using `var` here, the script calls `ltf()` only once, on the dataset's first bar, instead of redundantly
// evaluating unchanging strings on every bar. We only need one evaluation of this function because the selected
// timeframe does not change across bars in this script.
var string ltfString = LTF.ltf(ltfModeInput, LTF1, LTF2, LTF3, LTF4, LTF5, LTF6, LTF7, LTF8, LTF9, LTF10, LTF11, LTF12)
// @variable An array containing all intrabar `close` prices from the `ltfString` timeframe for the current chart bar.
array intrabarCloses = request.security_lower_tf(syminfo.tickerid, ltfString, close)
// Calculate the intrabar stats.
= LTF.ltfStats(intrabarCloses)
int chartBars = bar_index + 1
// ————— Visuals
// Plot the `avgIntrabars` and `intrabars` series in all display locations.
plot(avgIntrabars, "Average intrabars", color.silver, 6)
plot(intrabars, "Intrabars", color.blue, 2)
// Plot the `chartBarsCovered` and `chartBars` values in the Data Window and the script's status line.
plot(chartBarsCovered, "Chart bars covered", display = display.data_window + display.status_line)
plot(chartBars, "Chart bars total", display = display.data_window + display.status_line)
// Information box logic.
if showInfoBoxInput
// @variable A single-cell table that displays intrabar information.
var table infoBox = table.new(infoBoxYPosInput + "_" + infoBoxXPosInput, 1, 1)
// @variable The span of the `ltfString` timeframe formatted as a number of automatically selected time units.
string formattedLtf = PCtime.formattedNoOfPeriods(timeframe.in_seconds(ltfString) * 1000)
// @variable A "string" containing the formatted text to display in the `infoBox`.
string txt = str.format(
TAB_TXT, formattedLtf, avgIntrabars, chartBarsCovered, chartBars, chartBarsCovered / chartBars * 100, "'"
)
// Initialize the `infoBox` cell on the first bar.
if barstate.isfirst
table.cell(
infoBox, 0, 0, txt, text_color = infoBoxTxtColorInput, text_size = infoBoxSizeInput,
bgcolor = infoBoxColorInput
)
// Update the cell's text on the latest bar.
else if barstate.islast
table.cell_set_text(infoBox, 0, 0, txt)
// Raise a runtime error if no intrabar data is available.
if ta.cum(intrabars) == 0 and barstate.islast
runtime.error(str.format(ERR_TXT, ltfString, "'"))
//#endregion
█ EXPORTED FUNCTIONS
ltf(userSelection, choice1, choice2, ...)
Returns the optimal lower timeframe string based on user selection and current chart timeframe. Dynamically calculates precision to balance granularity with historical coverage within the 200K intrabar limit.
ltfStats(intrabarValues)
Analyzes an intrabar array returned by request.security_lower_tf() and returns statistics: number of intrabars in current bar, total chart bars covered, and average intrabars per bar.
█ CREDITS AND LICENSING
Original Concept : PineCoders Team
Original Lower TF Library :
License : Mozilla Public License 2.0
PriceFormatLibrary for automatically converting price values to formatted strings
matching the same format that TradingView uses to display open/high/low/close prices on the chart.
█ OVERVIEW
This library is intended for Pine Coders who are authors of scripts that display numbers onto a user's charts. Typically, 𝚜𝚝𝚛.𝚝𝚘𝚜𝚝𝚛𝚒𝚗𝚐() would be used to convert a number into a string which can be displayed in a label / box / table, but this only works well for values that are formatted as a simple decimal number. The purpose of this library is to provide an easy way to create a formatted string for values which use other types of formats besides the decimal format.
The main functions exported by this library are:
𝚏𝚘𝚛𝚖𝚊𝚝𝙿𝚛𝚒𝚌𝚎() - creates a formatted string from a price value
𝚖𝚎𝚊𝚜𝚞𝚛𝚎𝙿𝚛𝚒𝚌𝚎𝙲𝚑𝚊𝚗𝚐𝚎() - creates a formatted string from the distance between two prices
𝚝𝚘𝚜𝚝𝚛𝚒𝚗𝚐() - an alternative to the built-in 𝚜𝚝𝚛.𝚝𝚘𝚜𝚝𝚛𝚒𝚗𝚐(𝚟𝚊𝚕𝚞𝚎, 𝚏𝚘𝚛𝚖𝚊𝚝)
This library also exports some auxiliary functions which are used under the hood of the previously mentioned functions, but can also be useful to Pine Coders that need fine-tuned control for customized formatting of numeric values:
Functions that determine information about the current chart:
𝚒𝚜𝙵𝚛𝚊𝚌𝚝𝚒𝚘𝚗𝚊𝚕𝙵𝚘𝚛𝚖𝚊𝚝(), 𝚒𝚜𝚅𝚘𝚕𝚞𝚖𝚎𝙵𝚘𝚛𝚖𝚊𝚝(), 𝚒𝚜𝙿𝚎𝚛𝚌𝚎𝚗𝚝𝚊𝚐𝚎𝙵𝚘𝚛𝚖𝚊𝚝(), 𝚒𝚜𝙳𝚎𝚌𝚒𝚖𝚊𝚕𝙵𝚘𝚛𝚖𝚊𝚝(), 𝚒𝚜𝙿𝚒𝚙𝚜𝙵𝚘𝚛𝚖𝚊𝚝()
Functions that convert a 𝚏𝚕𝚘𝚊𝚝 value to a formatted string:
𝚊𝚜𝙳𝚎𝚌𝚒𝚖𝚊𝚕(), 𝚊𝚜𝙿𝚒𝚙𝚜(), 𝚊𝚜𝙵𝚛𝚊𝚌𝚝𝚒𝚘𝚗𝚊𝚕(), 𝚊𝚜𝚅𝚘𝚕𝚞𝚖𝚎()
█ EXAMPLES
• Simple Example
This example shows the simplest way to utilize this library.
//@version=6
indicator("Simple Example")
import n00btraders/PriceFormat/1
var table t = table.new(position.middle_right, 2, 1, bgcolor = color.new(color.blue, 90), force_overlay = true)
if barstate.isfirst
table.cell(t, 0, 0, "Current Price: ", text_color = color.black, text_size = 40)
table.cell(t, 1, 0, text_color = color.blue, text_size = 40)
if barstate.islast
string lastPrice = close.formatPrice() // Simple, easy way to format price
table.cell_set_text(t, 1, 0, lastPrice)
• Complex Example
This example calls all of the main functions and uses their optional arguments.
//@version=6
indicator("Complex Example")
import n00btraders/PriceFormat/1
// Enum values that can be used as optional arguments
precision = input.enum(PriceFormat.Precision.DEFAULT)
language = input.enum(PriceFormat.Language.ENGLISH)
// Main library functions used to create formatted strings
string formattedOpen = open.formatPrice(precision, language, allowPips = true)
string rawOpenPrice = PriceFormat.tostring(open, format.price)
string formattedClose = close.formatPrice(precision, language, allowPips = true)
string rawClosePrice = PriceFormat.tostring(close, format.price)
= PriceFormat.measurePriceChange(open, close, precision, language, allowPips = true)
// Labels to display formatted values on chart
string prices = str.format("Open: {0} ({1})\n\nClose: {2} ({3})", formattedOpen, rawOpenPrice, formattedClose, rawClosePrice)
string change = str.format("Change (close - open):\n\n{0} / {1}", distance, ticks)
label.new(chart.point.now(high), prices, yloc = yloc.abovebar, textalign = text.align_left, force_overlay = true)
label.new(chart.point.now(low), change, yloc = yloc.belowbar, style = label.style_label_up, force_overlay = true)
█ NOTES
• Function Descriptions
The library source code uses Markdown for the exported functions. Hover over a function/method call in the Pine Editor to display formatted, detailed information about the function/method.
• Precision Settings
The Precision option in the chart settings can change the format of how prices are displayed on the chart. Since the user's selected choice cannot be known through any Pine built-in variable, this library provides a 𝙿𝚛𝚎𝚌𝚒𝚜𝚒𝚘𝚗 enum that can be used as an optional script input for the user to specify their selected choice.
• Language Settings
The Language option in the user menu can change the decimal/grouping separators in the prices that are displayed on the chart. Since the user's selected choice cannot be known through any Pine built-in variable, this library provides a 𝙻𝚊𝚗𝚐𝚞𝚊𝚐𝚎 enum that can be used as an optional script input for the user to specify their selected choice.
█ EXPORTED FUNCTIONS
method formatPrice(price, precision, language, allowPips)
Formats a price value to match how it would be displayed on the user's current chart.
Namespace types: series float, simple float, input float, const float
Parameters:
price (float) : The value to format.
precision (series Precision) : A Precision.* enum value.
language (series Language) : A Language.* enum value.
allowPips (simple bool) : Whether to allow decimal numbers to display as pips.
Returns: Automatically formatted price string.
measurePriceChange(startPrice, endPrice, precision, language, allowPips)
Measures a change in price in terms of both distance and ticks.
Parameters:
startPrice (float) : The starting price.
endPrice (float) : The ending price.
precision (series Precision) : A Precision.* enum value.
language (series Language) : A Language.* enum value.
allowPips (simple bool) : Whether to allow decimal numbers to display as pips.
Returns: A tuple of formatted strings: .
method tostring(value, format)
Alternative to the Pine `str.tostring(value, format)` built-in function.
Namespace types: series float, simple float, input float, const float
Parameters:
value (float) : (series float) The value to format.
format (string) : (series string) The format string.
Returns: String in the specified format.
isFractionalFormat()
Determines if the default behavior of the chart's price scale is to use a fractional format.
Returns: True if the chart can display prices in fractional format.
isVolumeFormat()
Determines if the default behavior of the chart's price scale is to display prices as volume.
Returns: True if the chart can display prices as volume.
isPercentageFormat()
Determines if the default behavior of the chart's price scale is to display percentages.
Returns: True if the chart can display prices as percentages.
isDecimalFormat()
Determines if the default behavior of the chart's price scale is to use a decimal format.
Returns: True if the chart can display prices in decimal format.
isPipsFormat()
Determines if the current symbol's prices can be displayed as pips.
Returns: True if the chart can display prices as pips.
method asDecimal(value, precision, minTick, decimalSeparator, groupingSeparator, eNotation)
Converts a number to a string in decimal format.
Namespace types: series float, simple float, input float, const float
Parameters:
value (float) : The value to format.
precision (int) : Number of decimal places.
minTick (float) : Minimum tick size.
decimalSeparator (string) : The decimal separator.
groupingSeparator (string) : The thousands separator, aka digit group separator.
eNotation (bool) : Whether the result should use E notation.
Returns: String in decimal format.
method asPips(value, priceScale, minMove, minMove2, decimalSeparator, groupingSeparator)
Converts a number to a string in decimal format with the last digit replaced by a superscript.
Namespace types: series float, simple float, input float, const float
Parameters:
value (float) : The value to format.
priceScale (int) : Price scale.
minMove (int) : Min move.
minMove2 (int) : Min move 2.
decimalSeparator (string) : The decimal separator.
groupingSeparator (string) : The thousands separator, aka digit group separator.
Returns: String in decimal format with an emphasis on the pip value.
method asFractional(value, priceScale, minMove, minMove2, fractionalSeparator1, fractionalSeparator2)
Converts a number to a string in fractional format.
Namespace types: series float, simple float, input float, const float
Parameters:
value (float) : The value to format.
priceScale (int) : Price scale.
minMove (int) : Min move.
minMove2 (int) : Min move 2.
fractionalSeparator1 (string) : The primary fractional separator.
fractionalSeparator2 (string) : The secondary fractional separator.
Returns: String in fractional format.
method asVolume(value, precision, minTick, decimalSeparator, groupingSeparator, spacing)
Converts a number to a string in volume format.
Namespace types: series float, simple float, input float, const float
Parameters:
value (float) : The value to format.
precision (int) : Maximum number of decimal places.
minTick (float) : Minimum tick size.
decimalSeparator (string) : The decimal separator.
groupingSeparator (string) : The thousands separator, aka digit group separator.
spacing (string) : The whitespace separator.
Returns: String in volume format.
Time & Sales , Volume Delta and CVD, Volume imbalance , Tick
This Pine Script (version 6) creates a comprehensive TradingView indicator combining Time & Sales (Tape) with Volume Delta, Order Flow Pressure Indicator (OFPI), Volume Imbalance detection, Volume Delta (VD) histogram, Cumulative Volume Delta (CVD), TICK.US histogram, and a summary gauge table. It overlays on the chart with customizable tables, boxes, lines, and labels for real-time trade analysis, momentum, imbalances, and volume metrics.
Key Features and Components:
Time & Sales Table: A dynamic table showing recent trades (up to user-defined rows). Columns include Time, Side (▲/▼), Last Price, Volume (or Price-Weighted Volume). Trades below a volume threshold are hidden. Includes a buy/sell scale bar with percentages. Supports timeframe-based or live tick data fetching.
OFPI with Gauge: Calculates net aggressive volume pressure using bar body position, smoothed with T3 moving average. Displays a centered gauge bar (e.g., "░░░|███░░") indicating bullish/bearish momentum or shifts.
Volume Imbalance (VI): Detects bullish/bearish gaps between bars. Draws semi-transparent boxes with labels (e.g., "5 tks (vi)") for imbalances or gaps. Limits display to a max number, removes filled ones, and uses magnets (🧲) for gaps.
Volume Delta (VD): Approximates buy/sell delta via intrabar pressure or polarity. Displays as unipolar/bipolar histogram, optionally overlapping with regular volume or TICK.US. Shows numerical values (green/red/orange for divergences) and price/VD divergences.
Cumulative Volume Delta (CVD): Cumulates VD, reset on anchor timeframe (e.g., daily). Displays as line, area, baseline, or candles. Includes optional EMA smoothing and background fills. Detects divergences with price.
TICK.US Histogram: Overlays US Tick index (from symbol "TICK.US") as positive/negative bars during US market hours (9:30-16:00 ET, Mon-Fri). Replaces regular volume in some modes.
Gauge Summary Table: Bottom-left table with momentum text, OFPI gauge, CVD value, current Tick, and last bar's volume breakdown (total/buy/sell/delta).
Customization Options:
General: Timezone, date format, table position/size, colors (gradients for up/down), calculation mode (timeframe/live tick), volume type (volume/price-volume), thresholds, lengths (e.g., lookback, smoothing).
Display: Heights/offsets for histograms, line widths/styles, transparencies, label sizes/alignments, divergences, MA on volume, CVD smoothing/background.
Technical: Lower timeframe precision (auto or custom), anchor for CVD reset, max VIs to show.
Other: Toggles for VI, TICK.US, numerical values, divergences.
Credit
// FuturesCall @ fcalgobot.com
//Time & Sales (Tape)
// CVD base on Luxalgo CVD indicator
// Momentum Gauge by DskyzInvestments
// volume imbalance by ...
Qualitative and Quantitative Candlestick Score [CHE] Qualitative and Quantitative Candlestick Score
Overview
The Qualitative and Quantitative Candlestick Score is a powerful indicator for TradingView that combines both qualitative and quantitative analyses of candlestick patterns. This indicator provides traders with a comprehensive assessment of market conditions to make informed trading decisions.
Key Features
- Quantitative Analysis: Calculates a quantitative score based on the price movement of each candle.
- Qualitative Analysis: Evaluates candles based on body size, wick size, trend, and trading volume.
- Cumulative Scores: Displays cumulative green (bullish) and red (bearish) scores over a defined period.
- Trend Analysis: Identifies trend direction, strength, and provides trading recommendations (Long/Short).
- Customizable Settings: Adjust parameters for time periods, thresholds, and volume analysis.
Settings and Customizations
1. Time Period Settings:
- Period: Number of periods to calculate moving averages and cumulative scores (Default: 14).
2. Qualitative Evaluation:
- Body Size Threshold (%): Minimum size of the candle body to be considered significant (Default: 0.5%).
- Wick Size Threshold (%): Maximum size of the wicks to be considered minimal (Default: 0.3%).
3. Volume Settings:
- Include Volume in Evaluation: Whether to include trading volume in the qualitative score (Default: Enabled).
- Volume MA Period: Number of periods to calculate the moving average of volume (Default: 14).
4. Trend Settings:
- Moving Average Length: Number of periods for the Simple Moving Average used to determine the trend (Default: 50).
Calculations and Visualizations
- Quantitative Score: Difference between the closing and opening price, normalized to the opening price.
- Qualitative Score: Evaluation based on body size, wick size, trend, and volume.
- Cumulative Scores: Average of green and red scores over the defined period.
- Score Difference: Difference between cumulative green and red scores to determine trend direction.
- Trend Analysis Table: Displays trend direction, trend strength, and trading recommendation in an easy-to-read table.
Plotting and Display
- Cumulative Scores: Displays cumulative green and red scores in green and red colors.
- Score Difference: Blue line chart to visualize the difference between green and red scores.
- Zero Line: Horizontal gray line as a reference point.
- Trend Analysis Table: Table in the top right of the chart showing current trend direction, strength, and trading recommendation.
Use Cases
- Trend Identification: Use the score difference and trend analysis table to quickly assess the current market sentiment.
- Trading Recommendations: Based on the table, decide whether a long or short entry is appropriate.
- Volume Analysis: Including volume helps to better understand the strength of a trend.
Benefits
- Comprehensive Analysis: Combines quantitative and qualitative methods for a deeper market analysis.
- User-Friendly: Easy parameter adjustments allow for personalized use.
- Visually Appealing: Clear charts and tables facilitate data interpretation.
- Flexible: Adaptable to various trading strategies and timeframes.
Installation and Usage
1. Installation:
- Copy the provided Pine Script code.
- Go to TradingView and open the Pine Script Editor.
- Paste the code and save the script.
- Add the indicator to your chart.
2. Customization:
- Adjust the parameters according to your trading preferences.
- Monitor the cumulative scores and the trend analysis table for trading decisions.
Conclusion
The Qualitative and Quantitative Candlestick Score offers a comprehensive analysis of market conditions by combining quantitative and qualitative evaluation methods. With its user-friendly settings and clear visualizations, this indicator is a valuable tool for traders seeking informed and precise trading decisions.
Best regards and happy trading
Chervolino
Developed by: Chervolino
Version: 1.0
License: Free to use and customize on TradingView.
For any questions or feedback, feel free to contact me through the TradingView community.
Note: This indicator is a tool to assist with trading decisions and does not replace professional financial advice. Use it responsibly and thoroughly test it before incorporating it into your trading strategies.
Hypothesis TF Strategy EvaluationThis script provides a statistical evaluation framework for trend-following strategies by examining whether mean returns (measured here as 1-period Rate of Change, ROC) differ significantly across different price quantile groups.
Specifically, it:
Calculates rolling 25th (Q1) and 75th (Q3) percentile levels of price over a user-defined window.
Classifies returns into three groups based on whether price is above Q3, between Q1 and Q3, or below Q1.
Computes mean returns and sample sizes for each group.
Performs Welch's t-tests (which account for unequal variances) between groups to assess if their mean returns differ significantly.
Displays results in two tables:
Summary Table: Shows mean ROC and number of observations for each group.
Hypothesis Testing Table: Shows pairwise t-statistics with significance stars for 95% and 99% confidence levels.
Key Features
Rolling quantile calculations: Captures local price distributions dynamically.
Robust hypothesis testing: Welch's t-test allows for heteroskedasticity between groups.
Significance indicators: Easy visual interpretation with "*" (95%) and "**" (99%) significance levels.
Visual aids: Plots Q1 and Q3 levels on the price chart for intuitive understanding.
Extensible and transparent: Fully commented code that emphasizes the evaluation process rather than trading signals.
Important Notes
Not a trading strategy: This script is intended as a tool for research and validation, not as a standalone trading system.
Look-ahead bias caution: The calculation carefully avoids look-ahead bias by computing quantiles and ROC values only on past data at each point.
Users must ensure look-ahead bias is removed when applying this or similar methods, as look-ahead bias would artificially inflate performance and statistical significance.
The statistical tests rely on the assumption of independent samples, which might not fully hold in financial time series but still provide useful insights
Usage Suggestions
Use this evaluation framework to validate hypotheses about the behavior of returns under different price regimes.
Integrate with your strategy development workflow to test whether certain market conditions produce statistically distinct return distributions.
Example
In this example, the script was run with a quantile length of 20 bars and a lookback of 500 bars for ROC classification.
We consider a simple hypothetical "strategy":
Go long if the previous bar closed above Q3 the 75th percentile).
Go short if the previous bar closed below Q1 (the 25th percentile).
Stay in cash if the previous close was between Q1 and Q3.
The screenshot below demonstrates the results of this evaluation. Surprisingly, the "long" group shows a negative average return, while the "short" group has a positive average return, indicating mean reversion rather than trend following.
The hypothesis testing table confirms that the only statistically significant difference (at 95% or higher confidence) is between the above Q3 and below Q1 groups, suggesting a meaningful divergence in their return behavior.
This highlights how this framework can help validate or challenge intuitive assumptions about strategy performance through rigorous statistical testing.
cd_sweep&cisd_CxOverview:
When the price is at a significant zone/level on a higher time frame (HTF), and it sweeps (breaks through and then closes back below/above) the high or low of the previous HTF candle, it is common to look for a Change in State of Delivery (CISD) on a lower time frame (LTF) to enter a trade.
This model can be summarized as:
HTF Sweep → LTF CISD (Optional: SMT / Divergences)
________________________________________
Working Principle & Details:
1. The indicator monitors price action on the selected HTF and tracks any sweep (violation) of the previous HTF candle's high or low. Simultaneously, it identifies CISD levels on the LTF. If SMT is enabled, it will appear as a label on the chart.
When both HTF sweep and LTF CISD conditions are met, the indicator marks the chart at the open of the next candle and triggers an alert if set.
CISD levels are tracked and updated whenever a new HTF high/low is formed.
2. The indicator monitors the formation of entry models on up to six selected pairs, displaying results in two separate tables:
o HTF Sweep Query Table: Monitors live HTF candles and reports pairs that meet the sweep condition.
o CISD Table: Displays the pairs where a valid entry model has formed. A "🔥" symbol indicates the condition has occurred.
3. Bias Visualization:
Based on the selected HTF, a visual band is shown at the bottom of the chart using the chosen bullish/bearish colors.
Bias is determined by:
o Candle closing above/below the previous one suggesting continuation.
o A failed close after a sweep implying potential reversal.
4. HTF Candles:
Displays HTF candles based on the user-defined time frame.
5. Optional SMT (Smart Money Technique):
Must be enabled in the menu and requires the correlated pair to be entered correctly for accurate results.
Displayed only as a visual confirmation, not a requirement for model formation.
If the currently open symbol sweeps the previous candle while the correlated symbol does not (or vice versa), an "SMT" label appears on the chart.
6. Color & Table Positioning:
Controlled via the settings menu.
________________________________________
Warnings:
• The indicator only marks CISDs that form at HTF high/low zones.
• Entering every time the model forms does not guarantee profitability.
• Waiting for the model to appear at significant HTF levels/zones increases the likelihood of success.
• HTF and LTF selections should follow commonly accepted combinations or user-tested time frames.
• If you want to trigger alerts only for symbols entered in the indicator, ensure the "Use indicator alerts" option is enabled.
• To set alerts for the TradingView watchlist instead, disable the "Use indicator alerts" option.
________________________________________
Feel free to share your thoughts and suggestions.
Happy trading! 💫
dataTableUtilitiesLibrary "dataTableUtilities"
generate_dataTable(dataTable_map, title, tableYpos, tableXpos, textSize, includes_multiple_maps, include_comments)
: Generates and shows a data table.
Parameters:
dataTable_map (map)
title (string) : (string): Title of the table
tableYpos (string) : (string): Vertical position of the table
tableXpos (string) : (string): Horizontal position of the table
textSize (string) : (string): Text size
includes_multiple_maps (bool)
include_comments (bool)
Returns: : None
generate_dataTable_multiple_columns(dataTable_map, title, tableYpos, tableXpos, textSize, includes_multiple_maps, total_columns)
: Generates and shows a data table.
Parameters:
dataTable_map (map)
title (string) : (string): Title of the table
tableYpos (string) : (string): Vertical position of the table
tableXpos (string) : (string): Horizontal position of the table
textSize (string) : (string): Text size
includes_multiple_maps (bool)
total_columns (int)
Returns: : None
Streamer WatermarkThis unique indicator doesn’t help you trade but it makes your charts look super clean and professional in images and live streams! This indicator works by displaying two tables. The first table has day of the week, date, and free form text. The second table has ticker symbol and timeframe of the current chart.
Everything about the tables and the cells is completely controllable by the user! Here is a breakdown of how customizable the user can make this indicator:
Table:
Toggle each table to be displayed on or off
Move each table into 9 different locations around the chart
Move each table separately
Table background color and transparency
Table border color and transparency
Table border width
Table frame width
Cells:
Each cell can be individually toggled on or off (the table will resize dynamically)
Cell text color and transparency
Text size with 6 different options
Date format with 12 different formats
Input Text:
Text
Emoji
Text & emojis
ASCII characters
Symbols
Anything that can by copied and pasted
Any combination of the above
Notes
Use text size “Auto” if viewing the same chart on desktop and on smart phone (Auto makes the text scale based upon screen size)
Gallery
Disclaimer
Please read the TradingView House Rules carefully before using this indicator to add text, symbols, characters, or anything else to your charts and posting on TradingView Ideas or Scripts. This indicator and the author are not responsible for users not reading, fully understanding, and abiding by TradingView’s House Rules. Please watermark responsibly.
Dee EMA 5.0
1. Indicator Features:
- The indicator can plot four different sets of EMA on a chart.
- The EMA values can be displayed on the chart with their respective names (e.g., ema9, ema20, etc.).
- The indicator allows customization of the EMA values.
2. Purpose of Dee_EMA 5.0:
- Dee_EMA 5.0 is a unique EMA indicator specially designed for traders to provide better insights and aid in trading decisions.
- The primary reason for building this indicator is to address the challenge of managing multiple time frames while using normal EMA tables.
- Traditional EMA tables might not show all EMA values across different time frames simultaneously, leading to time-consuming processes like shifting time frames and refreshing charts.
- Dee_EMA 5.0 solves this issue by displaying EMA values for different time frames in one table, allowing traders to make quick judgments without repeatedly changing time frames and refreshing charts.
3. Importance of Different Time Frame EMA Values:
- Different time frames EMA values are crucial in trading because they provide valuable insights into the market dynamics at various levels.
- When using shorter time frames (e.g., 1-minute), EMA values can help identify short-term trends, support, and resistance levels.
- On the other hand, using larger time frames (e.g., 5-minute or 15-minute) provides more data and increases the accuracy of EMA-based analysis, enabling traders to identify longer-term trends and potential price movements.
4. EMA Crossover Table:
- Traders often prefer a clutter-free chart without too many lines, but they still need access to EMA values for analysis.
- The EMA table and EMA crossover table serve this purpose by providing EMA values and EMA crossover information in a structured table format.
- With the EMA crossover table, traders can quickly check EMA values and crossovers across different time frames without having to switch time frames repeatedly, saving time and facilitating faster decision-making during trading.
In summary, Dee_EMA 5.0 is an EMA indicator designed to help traders efficiently analyze EMA values across different time frames, allowing for faster and more informed trading decisions. The EMA crossover table provides additional convenience by presenting EMA crossovers without cluttering the chart.
CNTLibraryLibrary "CNTLibrary"
Custom Functions To Help Code In Pinescript V5
Coded By Christian Nataliano
First Coded In 10/06/2023
Last Edited In 22/06/2023
Huge Shout Out To © ZenAndTheArtOfTrading and his ZenLibrary V5, Some Of The Custom Functions Were Heavily Inspired By Matt's Work & His Pine Script Mastery Course
Another Shout Out To The TradingView's Team Library ta V5
//====================================================================================================================================================
// Custom Indicator Functions
//====================================================================================================================================================
GetKAMA(KAMA_lenght, Fast_KAMA, Slow_KAMA)
Calculates An Adaptive Moving Average Based On Perry J Kaufman's Calculations
Parameters:
KAMA_lenght (int) : Is The KAMA Lenght
Fast_KAMA (int) : Is The KAMA's Fastes Moving Average
Slow_KAMA (int) : Is The KAMA's Slowest Moving Average
Returns: Float Of The KAMA's Current Calculations
GetMovingAverage(Source, Lenght, Type)
Get Custom Moving Averages Values
Parameters:
Source (float) : Of The Moving Average, Defval = close
Lenght (simple int) : Of The Moving Average, Defval = 50
Type (string) : Of The Moving Average, Defval = Exponential Moving Average
Returns: The Moving Average Calculation Based On Its Given Source, Lenght & Calculation Type (Please Call Function On Global Scope)
GetDecimals()
Calculates how many decimals are on the quote price of the current market © ZenAndTheArtOfTrading
Returns: The current decimal places on the market quote price
Truncate(number, decimalPlaces)
Truncates (cuts) excess decimal places © ZenAndTheArtOfTrading
Parameters:
number (float)
decimalPlaces (simple float)
Returns: The given number truncated to the given decimalPlaces
ToWhole(number)
Converts pips into whole numbers © ZenAndTheArtOfTrading
Parameters:
number (float)
Returns: The converted number
ToPips(number)
Converts whole numbers back into pips © ZenAndTheArtOfTrading
Parameters:
number (float)
Returns: The converted number
GetPctChange(value1, value2, lookback)
Gets the percentage change between 2 float values over a given lookback period © ZenAndTheArtOfTrading
Parameters:
value1 (float)
value2 (float)
lookback (int)
BarsAboveMA(lookback, ma)
Counts how many candles are above the MA © ZenAndTheArtOfTrading
Parameters:
lookback (int)
ma (float)
Returns: The bar count of how many recent bars are above the MA
BarsBelowMA(lookback, ma)
Counts how many candles are below the MA © ZenAndTheArtOfTrading
Parameters:
lookback (int)
ma (float)
Returns: The bar count of how many recent bars are below the EMA
BarsCrossedMA(lookback, ma)
Counts how many times the EMA was crossed recently © ZenAndTheArtOfTrading
Parameters:
lookback (int)
ma (float)
Returns: The bar count of how many times price recently crossed the EMA
GetPullbackBarCount(lookback, direction)
Counts how many green & red bars have printed recently (ie. pullback count) © ZenAndTheArtOfTrading
Parameters:
lookback (int)
direction (int)
Returns: The bar count of how many candles have retraced over the given lookback & direction
GetSwingHigh(Lookback, SwingType)
Check If Price Has Made A Recent Swing High
Parameters:
Lookback (int) : Is For The Swing High Lookback Period, Defval = 7
SwingType (int) : Is For The Swing High Type Of Identification, Defval = 1
Returns: A Bool - True If Price Has Made A Recent Swing High
GetSwingLow(Lookback, SwingType)
Check If Price Has Made A Recent Swing Low
Parameters:
Lookback (int) : Is For The Swing Low Lookback Period, Defval = 7
SwingType (int) : Is For The Swing Low Type Of Identification, Defval = 1
Returns: A Bool - True If Price Has Made A Recent Swing Low
//====================================================================================================================================================
// Custom Risk Management Functions
//====================================================================================================================================================
CalculateStopLossLevel(OrderType, Entry, StopLoss)
Calculate StopLoss Level
Parameters:
OrderType (int) : Is To Determine A Long / Short Position, Defval = 1
Entry (float) : Is The Entry Level Of The Order, Defval = na
StopLoss (float) : Is The Custom StopLoss Distance, Defval = 2x ATR Below Close
Returns: Float - The StopLoss Level In Actual Price As A
CalculateStopLossDistance(OrderType, Entry, StopLoss)
Calculate StopLoss Distance In Pips
Parameters:
OrderType (int) : Is To Determine A Long / Short Position, Defval = 1
Entry (float) : Is The Entry Level Of The Order, NEED TO INPUT PARAM
StopLoss (float) : Level Based On Previous Calculation, NEED TO INPUT PARAM
Returns: Float - The StopLoss Value In Pips
CalculateTakeProfitLevel(OrderType, Entry, StopLossDistance, RiskReward)
Calculate TakeProfit Level
Parameters:
OrderType (int) : Is To Determine A Long / Short Position, Defval = 1
Entry (float) : Is The Entry Level Of The Order, Defval = na
StopLossDistance (float)
RiskReward (float)
Returns: Float - The TakeProfit Level In Actual Price
CalculateTakeProfitDistance(OrderType, Entry, TakeProfit)
Get TakeProfit Distance In Pips
Parameters:
OrderType (int) : Is To Determine A Long / Short Position, Defval = 1
Entry (float) : Is The Entry Level Of The Order, NEED TO INPUT PARAM
TakeProfit (float) : Level Based On Previous Calculation, NEED TO INPUT PARAM
Returns: Float - The TakeProfit Value In Pips
CalculateConversionCurrency(AccountCurrency, SymbolCurrency, BaseCurrency)
Get The Conversion Currecny Between Current Account Currency & Current Pair's Quoted Currency (FOR FOREX ONLY)
Parameters:
AccountCurrency (simple string) : Is For The Account Currency Used
SymbolCurrency (simple string) : Is For The Current Symbol Currency (Front Symbol)
BaseCurrency (simple string) : Is For The Current Symbol Base Currency (Back Symbol)
Returns: Tuple Of A Bollean (Convert The Currency ?) And A String (Converted Currency)
CalculateConversionRate(ConvertCurrency, ConversionRate)
Get The Conversion Rate Between Current Account Currency & Current Pair's Quoted Currency (FOR FOREX ONLY)
Parameters:
ConvertCurrency (bool) : Is To Check If The Current Symbol Needs To Be Converted Or Not
ConversionRate (float) : Is The Quoted Price Of The Conversion Currency (Input The request.security Function Here)
Returns: Float Price Of Conversion Rate (If In The Same Currency Than Return Value Will Be 1.0)
LotSize(LotSizeSimple, Balance, Risk, SLDistance, ConversionRate)
Get Current Lot Size
Parameters:
LotSizeSimple (bool) : Is To Toggle Lot Sizing Calculation (Simple Is Good Enough For Stocks & Crypto, Whilst Complex Is For Forex)
Balance (float) : Is For The Current Account Balance To Calculate The Lot Sizing Based Off
Risk (float) : Is For The Current Risk Per Trade To Calculate The Lot Sizing Based Off
SLDistance (float) : Is The Current Position StopLoss Distance From Its Entry Price
ConversionRate (float) : Is The Currency Conversion Rate (Used For Complex Lot Sizing Only)
Returns: Float - Position Size In Units
ToLots(Units)
Converts Units To Lots
Parameters:
Units (float) : Is For How Many Units Need To Be Converted Into Lots (Minimun 1000 Units)
Returns: Float - Position Size In Lots
ToUnits(Lots)
Converts Lots To Units
Parameters:
Lots (float) : Is For How Many Lots Need To Be Converted Into Units (Minimun 0.01 Units)
Returns: Int - Position Size In Units
ToLotsInUnits(Units)
Converts Units To Lots Than Back To Units
Parameters:
Units (float) : Is For How Many Units Need To Be Converted Into Lots (Minimun 1000 Units)
Returns: Float - Position Size In Lots That Were Rounded To Units
ATRTrail(OrderType, SourceType, ATRPeriod, ATRMultiplyer, SwingLookback)
Calculate ATR Trailing Stop
Parameters:
OrderType (int) : Is To Determine A Long / Short Position, Defval = 1
SourceType (int) : Is To Determine Where To Calculate The ATR Trailing From, Defval = close
ATRPeriod (simple int) : Is To Change Its ATR Period, Defval = 20
ATRMultiplyer (float) : Is To Change Its ATR Trailing Distance, Defval = 1
SwingLookback (int) : Is To Change Its Swing HiLo Lookback (Only From Source Type 5), Defval = 7
Returns: Float - Number Of The Current ATR Trailing
DangerZone(WinRate, AvgRRR, Filter)
Calculate Danger Zone Of A Given Strategy
Parameters:
WinRate (float) : Is The Strategy WinRate
AvgRRR (float) : Is The Strategy Avg RRR
Filter (float) : Is The Minimum Profit It Needs To Be Out Of BE Zone, Defval = 3
Returns: Int - Value, 1 If Out Of Danger Zone, 0 If BE, -1 If In Danger Zone
IsQuestionableTrades(TradeTP, TradeSL)
Checks For Questionable Trades (Which Are Trades That Its TP & SL Level Got Hit At The Same Candle)
Parameters:
TradeTP (float) : Is The Trade In Question Take Profit Level
TradeSL (float) : Is The Trade In Question Stop Loss Level
Returns: Bool - True If The Last Trade Was A "Questionable Trade"
//====================================================================================================================================================
// Custom Strategy Functions
//====================================================================================================================================================
OpenLong(EntryID, LotSize, LimitPrice, StopPrice, Comment, CommentValue)
Open A Long Order Based On The Given Params
Parameters:
EntryID (string) : Is The Trade Entry ID, Defval = "Long"
LotSize (float) : Is The Lot Size Of The Trade, Defval = 1
LimitPrice (float) : Is The Limit Order Price To Set The Order At, Defval = Na / Market Order Execution
StopPrice (float) : Is The Stop Order Price To Set The Order At, Defval = Na / Market Order Execution
Comment (string) : Is The Order Comment, Defval = Long Entry Order
CommentValue (string) : Is For Custom Values In The Order Comment, Defval = Na
Returns: Void
OpenShort(EntryID, LotSize, LimitPrice, StopPrice, Comment, CommentValue)
Open A Short Order Based On The Given Params
Parameters:
EntryID (string) : Is The Trade Entry ID, Defval = "Short"
LotSize (float) : Is The Lot Size Of The Trade, Defval = 1
LimitPrice (float) : Is The Limit Order Price To Set The Order At, Defval = Na / Market Order Execution
StopPrice (float) : Is The Stop Order Price To Set The Order At, Defval = Na / Market Order Execution
Comment (string) : Is The Order Comment, Defval = Short Entry Order
CommentValue (string) : Is For Custom Values In The Order Comment, Defval = Na
Returns: Void
TP_SLExit(FromID, TPLevel, SLLevel, PercentageClose, Comment, CommentValue)
Exits Based On Predetermined TP & SL Levels
Parameters:
FromID (string) : Is The Trade ID That The TP & SL Levels Be Palced
TPLevel (float) : Is The Take Profit Level
SLLevel (float) : Is The StopLoss Level
PercentageClose (float) : Is The Amount To Close The Order At (In Percentage) Defval = 100
Comment (string) : Is The Order Comment, Defval = Exit Order
CommentValue (string) : Is For Custom Values In The Order Comment, Defval = Na
Returns: Void
CloseLong(ExitID, PercentageClose, Comment, CommentValue, Instant)
Exits A Long Order Based On A Specified Condition
Parameters:
ExitID (string) : Is The Trade ID That Will Be Closed, Defval = "Long"
PercentageClose (float) : Is The Amount To Close The Order At (In Percentage) Defval = 100
Comment (string) : Is The Order Comment, Defval = Exit Order
CommentValue (string) : Is For Custom Values In The Order Comment, Defval = Na
Instant (bool) : Is For Exit Execution Type, Defval = false
Returns: Void
CloseShort(ExitID, PercentageClose, Comment, CommentValue, Instant)
Exits A Short Order Based On A Specified Condition
Parameters:
ExitID (string) : Is The Trade ID That Will Be Closed, Defval = "Short"
PercentageClose (float) : Is The Amount To Close The Order At (In Percentage) Defval = 100
Comment (string) : Is The Order Comment, Defval = Exit Order
CommentValue (string) : Is For Custom Values In The Order Comment, Defval = Na
Instant (bool) : Is For Exit Execution Type, Defval = false
Returns: Void
BrokerCheck(Broker)
Checks Traded Broker With Current Loaded Chart Broker
Parameters:
Broker (string) : Is The Current Broker That Is Traded
Returns: Bool - True If Current Traded Broker Is Same As Loaded Chart Broker
OpenPC(LicenseID, OrderType, UseLimit, LimitPrice, SymbolPrefix, Symbol, SymbolSuffix, Risk, SL, TP, OrderComment, Spread)
Compiles Given Parameters Into An Alert String Format To Open Trades Using Pine Connector
Parameters:
LicenseID (string) : Is The Users PineConnector LicenseID
OrderType (int) : Is The Desired OrderType To Open
UseLimit (bool) : Is If We Want To Enter The Position At Exactly The Previous Closing Price
LimitPrice (float) : Is The Limit Price Of The Trade (Only For Pending Orders)
SymbolPrefix (string) : Is The Current Symbol Prefix (If Any)
Symbol (string) : Is The Traded Symbol
SymbolSuffix (string) : Is The Current Symbol Suffix (If Any)
Risk (float) : Is The Trade Risk Per Trade / Fixed Lot Sizing
SL (float) : Is The Trade SL In Price / In Pips
TP (float) : Is The Trade TP In Price / In Pips
OrderComment (string) : Is The Executed Trade Comment
Spread (float) : is The Maximum Spread For Execution
Returns: String - Pine Connector Order Syntax Alert Message
ClosePC(LicenseID, OrderType, SymbolPrefix, Symbol, SymbolSuffix)
Compiles Given Parameters Into An Alert String Format To Close Trades Using Pine Connector
Parameters:
LicenseID (string) : Is The Users PineConnector LicenseID
OrderType (int) : Is The Desired OrderType To Close
SymbolPrefix (string) : Is The Current Symbol Prefix (If Any)
Symbol (string) : Is The Traded Symbol
SymbolSuffix (string) : Is The Current Symbol Suffix (If Any)
Returns: String - Pine Connector Order Syntax Alert Message
//====================================================================================================================================================
// Custom Backtesting Calculation Functions
//====================================================================================================================================================
CalculatePNL(EntryPrice, ExitPrice, LotSize, ConversionRate)
Calculates Trade PNL Based On Entry, Eixt & Lot Size
Parameters:
EntryPrice (float) : Is The Trade Entry
ExitPrice (float) : Is The Trade Exit
LotSize (float) : Is The Trade Sizing
ConversionRate (float) : Is The Currency Conversion Rate (Used For Complex Lot Sizing Only)
Returns: Float - The Current Trade PNL
UpdateBalance(PrevBalance, PNL)
Updates The Previous Ginve Balance To The Next PNL
Parameters:
PrevBalance (float) : Is The Previous Balance To Be Updated
PNL (float) : Is The Current Trade PNL To Be Added
Returns: Float - The Current Updated PNL
CalculateSlpComm(PNL, MaxRate)
Calculates Random Slippage & Commisions Fees Based On The Parameters
Parameters:
PNL (float) : Is The Current Trade PNL
MaxRate (float) : Is The Upper Limit (In Percentage) Of The Randomized Fee
Returns: Float - A Percentage Fee Of The Current Trade PNL
UpdateDD(MaxBalance, Balance)
Calculates & Updates The DD Based On Its Given Parameters
Parameters:
MaxBalance (float) : Is The Maximum Balance Ever Recorded
Balance (float) : Is The Current Account Balance
Returns: Float - The Current Strategy DD
CalculateWR(TotalTrades, LongID, ShortID)
Calculate The Total, Long & Short Trades Win Rate
Parameters:
TotalTrades (int) : Are The Current Total Trades That The Strategy Has Taken
LongID (string) : Is The Order ID Of The Long Trades Of The Strategy
ShortID (string) : Is The Order ID Of The Short Trades Of The Strategy
Returns: Tuple Of Long WR%, Short WR%, Total WR%, Total Winning Trades, Total Losing Trades, Total Long Trades & Total Short Trades
CalculateAvgRRR(WinTrades, LossTrades)
Calculates The Overall Strategy Avg Risk Reward Ratio
Parameters:
WinTrades (int) : Are The Strategy Winning Trades
LossTrades (int) : Are The Strategy Losing Trades
Returns: Float - The Average RRR Values
CAGR(StartTime, StartPrice, EndTime, EndPrice)
Calculates The CAGR Over The Given Time Period © TradingView
Parameters:
StartTime (int) : Is The Starting Time Of The Calculation
StartPrice (float) : Is The Starting Price Of The Calculation
EndTime (int) : Is The Ending Time Of The Calculation
EndPrice (float) : Is The Ending Price Of The Calculation
Returns: Float - The CAGR Values
//====================================================================================================================================================
// Custom Plot Functions
//====================================================================================================================================================
EditLabels(LabelID, X1, Y1, Text, Color, TextColor, EditCondition, DeleteCondition)
Edit / Delete Labels
Parameters:
LabelID (label) : Is The ID Of The Selected Label
X1 (int) : Is The X1 Coordinate IN BARINDEX Xloc
Y1 (float) : Is The Y1 Coordinate IN PRICE Yloc
Text (string) : Is The Text Than Wants To Be Written In The Label
Color (color) : Is The Color Value Change Of The Label Text
TextColor (color)
EditCondition (int) : Is The Edit Condition of The Line (Setting Location / Color)
DeleteCondition (bool) : Is The Delete Condition Of The Line If Ture Deletes The Prev Itteration Of The Line
Returns: Void
EditLine(LineID, X1, Y1, X2, Y2, Color, EditCondition, DeleteCondition)
Edit / Delete Lines
Parameters:
LineID (line) : Is The ID Of The Selected Line
X1 (int) : Is The X1 Coordinate IN BARINDEX Xloc
Y1 (float) : Is The Y1 Coordinate IN PRICE Yloc
X2 (int) : Is The X2 Coordinate IN BARINDEX Xloc
Y2 (float) : Is The Y2 Coordinate IN PRICE Yloc
Color (color) : Is The Color Value Change Of The Line
EditCondition (int) : Is The Edit Condition of The Line (Setting Location / Color)
DeleteCondition (bool) : Is The Delete Condition Of The Line If Ture Deletes The Prev Itteration Of The Line
Returns: Void
//====================================================================================================================================================
// Custom Display Functions (Using Tables)
//====================================================================================================================================================
FillTable(TableID, Column, Row, Title, Value, BgColor, TextColor, ToolTip)
Filling The Selected Table With The Inputed Information
Parameters:
TableID (table) : Is The Table ID That Wants To Be Edited
Column (int) : Is The Current Column Of The Table That Wants To Be Edited
Row (int) : Is The Current Row Of The Table That Wants To Be Edited
Title (string) : Is The String Title Of The Current Cell Table
Value (string) : Is The String Value Of The Current Cell Table
BgColor (color) : Is The Selected Color For The Current Table
TextColor (color) : Is The Selected Color For The Current Table
ToolTip (string) : Is The ToolTip Of The Current Cell In The Table
Returns: Void
DisplayBTResults(TableID, BgColor, TextColor, StartingBalance, Balance, DollarReturn, TotalPips, MaxDD)
Filling The Selected Table With The Inputed Information
Parameters:
TableID (table) : Is The Table ID That Wants To Be Edited
BgColor (color) : Is The Selected Color For The Current Table
TextColor (color) : Is The Selected Color For The Current Table
StartingBalance (float) : Is The Account Starting Balance
Balance (float)
DollarReturn (float) : Is The Account Dollar Reture
TotalPips (float) : Is The Total Pips Gained / loss
MaxDD (float) : Is The Maximum Drawdown Over The Backtesting Period
Returns: Void
DisplayBTResultsV2(TableID, BgColor, TextColor, TotalWR, QTCount, LongWR, ShortWR, InitialCapital, CumProfit, CumFee, AvgRRR, MaxDD, CAGR, MeanDD)
Filling The Selected Table With The Inputed Information
Parameters:
TableID (table) : Is The Table ID That Wants To Be Edited
BgColor (color) : Is The Selected Color For The Current Table
TextColor (color) : Is The Selected Color For The Current Table
TotalWR (float) : Is The Strategy Total WR In %
QTCount (int) : Is The Strategy Questionable Trades Count
LongWR (float) : Is The Strategy Total WR In %
ShortWR (float) : Is The Strategy Total WR In %
InitialCapital (float) : Is The Strategy Initial Starting Capital
CumProfit (float) : Is The Strategy Ending Cumulative Profit
CumFee (float) : Is The Strategy Ending Cumulative Fee (Based On Randomized Fee Assumptions)
AvgRRR (float) : Is The Strategy Average Risk Reward Ratio
MaxDD (float) : Is The Strategy Maximum DrawDown In Its Backtesting Period
CAGR (float) : Is The Strategy Compounded Average GRowth In %
MeanDD (float) : Is The Strategy Mean / Average Drawdown In The Backtesting Period
Returns: Void
//====================================================================================================================================================
// Custom Pattern Detection Functions
//====================================================================================================================================================
BullFib(priceLow, priceHigh, fibRatio)
Calculates A Bullish Fibonacci Value (From Swing Low To High) © ZenAndTheArtOfTrading
Parameters:
priceLow (float)
priceHigh (float)
fibRatio (float)
Returns: The Fibonacci Value Of The Given Ratio Between The Two Price Points
BearFib(priceLow, priceHigh, fibRatio)
Calculates A Bearish Fibonacci Value (From Swing High To Low) © ZenAndTheArtOfTrading
Parameters:
priceLow (float)
priceHigh (float)
fibRatio (float)
Returns: The Fibonacci Value Of The Given Ratio Between The Two Price Points
GetBodySize()
Gets The Current Candle Body Size IN POINTS © ZenAndTheArtOfTrading
Returns: The Current Candle Body Size IN POINTS
GetTopWickSize()
Gets The Current Candle Top Wick Size IN POINTS © ZenAndTheArtOfTrading
Returns: The Current Candle Top Wick Size IN POINTS
GetBottomWickSize()
Gets The Current Candle Bottom Wick Size IN POINTS © ZenAndTheArtOfTrading
Returns: The Current Candle Bottom Wick Size IN POINTS
GetBodyPercent()
Gets The Current Candle Body Size As A Percentage Of Its Entire Size Including Its Wicks © ZenAndTheArtOfTrading
Returns: The Current Candle Body Size IN PERCENTAGE
GetTopWickPercent()
Gets The Current Top Wick Size As A Percentage Of Its Entire Body Size
Returns: Float - The Current Candle Top Wick Size IN PERCENTAGE
GetBottomWickPercent()
Gets The Current Bottom Wick Size As A Percentage Of Its Entire Bodu Size
Returns: Float - The Current Candle Bottom Size IN PERCENTAGE
BullishEC(Allowance, RejectionWickSize, EngulfWick, NearSwings, SwingLookBack)
Checks If The Current Bar Is A Bullish Engulfing Candle
Parameters:
Allowance (int) : To Give Flexibility Of Engulfing Pattern Detection In Markets That Have Micro Gaps, Defval = 0
RejectionWickSize (float) : To Filter Out long (Upper And Lower) Wick From The Bullsih Engulfing Pattern, Defval = na
EngulfWick (bool) : To Specify If We Want The Pattern To Also Engulf Its Upper & Lower Previous Wicks, Defval = false
NearSwings (bool) : To Specify If We Want The Pattern To Be Near A Recent Swing Low, Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing Low, Defval = 10
Returns: Bool - True If The Current Bar Matches The Requirements of a Bullish Engulfing Candle
BearishEC(Allowance, RejectionWickSize, EngulfWick, NearSwings, SwingLookBack)
Checks If The Current Bar Is A Bearish Engulfing Candle
Parameters:
Allowance (int) : To Give Flexibility Of Engulfing Pattern Detection In Markets That Have Micro Gaps, Defval = 0
RejectionWickSize (float) : To Filter Out long (Upper And Lower) Wick From The Bearish Engulfing Pattern, Defval = na
EngulfWick (bool) : To Specify If We Want The Pattern To Also Engulf Its Upper & Lower Previous Wicks, Defval = false
NearSwings (bool) : To Specify If We Want The Pattern To Be Near A Recent Swing High, Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing High, Defval = 10
Returns: Bool - True If The Current Bar Matches The Requirements of a Bearish Engulfing Candle
Hammer(Fib, ColorMatch, NearSwings, SwingLookBack, ATRFilterCheck, ATRPeriod)
Checks If The Current Bar Is A Hammer Candle
Parameters:
Fib (float) : To Specify Which Fibonacci Ratio To Use When Determining The Hammer Candle, Defval = 0.382 Ratio
ColorMatch (bool) : To Filter Only Bullish Closed Hammer Candle Pattern, Defval = false
NearSwings (bool) : To Specify If We Want The Doji To Be Near A Recent Swing Low, Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing Low, Defval = 10
ATRFilterCheck (float) : To Filter Smaller Hammer Candles That Might Be Better Classified As A Doji Candle, Defval = 1
ATRPeriod (simple int) : To Change ATR Period Of The ATR Filter, Defval = 20
Returns: Bool - True If The Current Bar Matches The Requirements of a Hammer Candle
Star(Fib, ColorMatch, NearSwings, SwingLookBack, ATRFilterCheck, ATRPeriod)
Checks If The Current Bar Is A Hammer Candle
Parameters:
Fib (float) : To Specify Which Fibonacci Ratio To Use When Determining The Hammer Candle, Defval = 0.382 Ratio
ColorMatch (bool) : To Filter Only Bullish Closed Hammer Candle Pattern, Defval = false
NearSwings (bool) : To Specify If We Want The Doji To Be Near A Recent Swing Low, Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing Low, Defval = 10
ATRFilterCheck (float) : To Filter Smaller Hammer Candles That Might Be Better Classified As A Doji Candle, Defval = 1
ATRPeriod (simple int) : To Change ATR Period Of The ATR Filter, Defval = 20
Returns: Bool - True If The Current Bar Matches The Requirements of a Hammer Candle
Doji(MaxWickSize, MaxBodySize, DojiType, NearSwings, SwingLookBack)
Checks If The Current Bar Is A Doji Candle
Parameters:
MaxWickSize (float) : To Specify The Maximum Lenght Of Its Upper & Lower Wick, Defval = 2
MaxBodySize (float) : To Specify The Maximum Lenght Of Its Candle Body IN PERCENT, Defval = 0.05
DojiType (int)
NearSwings (bool) : To Specify If We Want The Doji To Be Near A Recent Swing High / Low (Only In Dragonlyf / Gravestone Mode), Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing High / Low (Only In Dragonlyf / Gravestone Mode), Defval = 10
Returns: Bool - True If The Current Bar Matches The Requirements of a Doji Candle
BullishIB(Allowance, RejectionWickSize, EngulfWick, NearSwings, SwingLookBack)
Checks If The Current Bar Is A Bullish Harami Candle
Parameters:
Allowance (int) : To Give Flexibility Of Harami Pattern Detection In Markets That Have Micro Gaps, Defval = 0
RejectionWickSize (float) : To Filter Out long (Upper And Lower) Wick From The Bullsih Harami Pattern, Defval = na
EngulfWick (bool) : To Specify If We Want The Pattern To Also Engulf Its Upper & Lower Previous Wicks, Defval = false
NearSwings (bool) : To Specify If We Want The Pattern To Be Near A Recent Swing Low, Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing Low, Defval = 10
Returns: Bool - True If The Current Bar Matches The Requirements of a Bullish Harami Candle
BearishIB(Allowance, RejectionWickSize, EngulfWick, NearSwings, SwingLookBack)
Checks If The Current Bar Is A Bullish Harami Candle
Parameters:
Allowance (int) : To Give Flexibility Of Harami Pattern Detection In Markets That Have Micro Gaps, Defval = 0
RejectionWickSize (float) : To Filter Out long (Upper And Lower) Wick From The Bearish Harami Pattern, Defval = na
EngulfWick (bool) : To Specify If We Want The Pattern To Also Engulf Its Upper & Lower Previous Wicks, Defval = false
NearSwings (bool) : To Specify If We Want The Pattern To Be Near A Recent Swing High, Defval = true
SwingLookBack (int) : To Specify How Many Bars Back To Detect A Recent Swing High, Defval = 10
Returns: Bool - True If The Current Bar Matches The Requirements of a Bearish Harami Candle
//====================================================================================================================================================
// Custom Time Functions
//====================================================================================================================================================
BarInSession(sess, useFilter)
Determines if the current price bar falls inside the specified session © ZenAndTheArtOfTrading
Parameters:
sess (simple string)
useFilter (bool)
Returns: A boolean - true if the current bar falls within the given time session
BarOutSession(sess, useFilter)
Determines if the current price bar falls outside the specified session © ZenAndTheArtOfTrading
Parameters:
sess (simple string)
useFilter (bool)
Returns: A boolean - true if the current bar falls outside the given time session
DateFilter(startTime, endTime)
Determines if this bar's time falls within date filter range © ZenAndTheArtOfTrading
Parameters:
startTime (int)
endTime (int)
Returns: A boolean - true if the current bar falls within the given dates
DayFilter(monday, tuesday, wednesday, thursday, friday, saturday, sunday)
Checks if the current bar's day is in the list of given days to analyze © ZenAndTheArtOfTrading
Parameters:
monday (bool)
tuesday (bool)
wednesday (bool)
thursday (bool)
friday (bool)
saturday (bool)
sunday (bool)
Returns: A boolean - true if the current bar's day is one of the given days
AUSSess()
Checks If The Current Australian Forex Session In Running
Returns: Bool - True If Currently The Australian Session Is Running
ASIASess()
Checks If The Current Asian Forex Session In Running
Returns: Bool - True If Currently The Asian Session Is Running
EURSess()
Checks If The Current European Forex Session In Running
Returns: Bool - True If Currently The European Session Is Running
USSess()
Checks If The Current US Forex Session In Running
Returns: Bool - True If Currently The US Session Is Running
UNIXToDate(Time, ConversionType, TimeZone)
Converts UNIX Time To Datetime
Parameters:
Time (int) : Is The UNIX Time Input
ConversionType (int) : Is The Datetime Output Format, Defval = DD-MM-YYYY
TimeZone (string) : Is To Convert The Outputed Datetime Into The Specified Time Zone, Defval = Exchange Time Zone
Returns: String - String Of Datetime






















